Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pigpio Testing #819

Merged
merged 42 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
13174a1
pigpio testing
TMRh20 Jan 3, 2022
7b549fc
pigpio
TMRh20 Jan 3, 2022
a87d8b9
Clean up comments/descriptor
TMRh20 Jan 3, 2022
af90c03
Forgot colon
TMRh20 Jan 3, 2022
52ff687
fix indent in linux CI
2bndy5 Jan 3, 2022
a9f4d35
[linux CI] try cross-compiling pigpio latest src
2bndy5 Jan 3, 2022
810c541
[linux CI] set pigpio make var from cli
2bndy5 Jan 3, 2022
a256b26
there may a problem with pigpio makefile's $(CC)
2bndy5 Jan 3, 2022
ed56e1f
Re-add pthread
TMRh20 Jan 3, 2022
21174d9
cross compile pigpio using our cmake toolchains
2bndy5 Jan 3, 2022
1777b22
Merge branch 'pigpio' of https://github.com/nRF24/RF24 into pigpio
2bndy5 Jan 3, 2022
7c62841
tell cmake to look for pigpio
2bndy5 Jan 3, 2022
283987b
IRQ example still incompatible w/ MRAA/wiringPi
2bndy5 Jan 3, 2022
9cef378
Add pigpio driver
TMRh20 Jan 8, 2022
fc5a79e
Update gpio.cpp
TMRh20 Jan 8, 2022
e96d393
Update spi files for pigpio
TMRh20 Jan 9, 2022
4796b8b
Merge branch 'pigpio_driver' into pigpio
TMRh20 Jan 9, 2022
690f2ed
pigpio - SPI at 1mhz default
TMRh20 Jan 9, 2022
3a920c1
Fix per review
TMRh20 Jan 9, 2022
a89b967
update build systems (needs HW testing)
2bndy5 Jan 9, 2022
00e6b6e
not sure what is wrong with cmake built examples
2bndy5 Jan 9, 2022
7e0f60e
don't provide pigpio for non-armhhf/aarch64 CI
2bndy5 Jan 9, 2022
8423ad8
fix logic in last CI change
2bndy5 Jan 9, 2022
c7e284d
[cmake] fix compiling irq example for pigpio
2bndy5 Jan 10, 2022
e9a6b3b
[cmake] allow RPi and SPIDEV to not use pigpio
2bndy5 Jan 10, 2022
5aae12f
typo in last commit
2bndy5 Jan 10, 2022
5d5cfd4
[cmake] examples avoid use irq for RPi/SPIDEV
2bndy5 Jan 10, 2022
b2be98e
c-n-p error in last commit
2bndy5 Jan 10, 2022
fcbd407
let py wrapper avoid irq if no pigpio found
2bndy5 Jan 10, 2022
4532552
fix logic in setup.py detecting pigpio
2bndy5 Jan 10, 2022
5bbd921
fix CMake buibld examples. prep for doxygen 1.9.3
2bndy5 Jan 12, 2022
0f63485
fix typo in cmake msg output
2bndy5 Jan 17, 2022
9c56bdd
[cmake] correct a var value when autodetect pigpio
2bndy5 Jan 18, 2022
1c6ff52
py wrapper link to pigpio if detected when built
2bndy5 Jan 18, 2022
a62ba4e
[CMake] allow explicitly disabling IRQ support
2bndy5 Jan 18, 2022
4eb1650
[cmake] allow driver to be set from env
2bndy5 Jan 24, 2022
b5cc8d0
add a cmake msg about disabling irq support
2bndy5 Jan 24, 2022
b175e14
Update linux_install.md
TMRh20 Jan 29, 2022
8ac6c02
do not include interrupt.h for python wrapper
2bndy5 Jan 30, 2022
0281ea5
update py wrapper install cmake doc & Linux CI
2bndy5 Jan 30, 2022
c0f5d45
properly link to pigpio driver in py wrapper
2bndy5 Jan 30, 2022
4744a0d
Update setup.py
2bndy5 Feb 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions .github/workflows/build_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,22 @@ jobs:
git clone https://github.com/WiringPi/WiringPi
cd WiringPi
./build


- name: provide pigpio
if: ${{ matrix.config-options != '--driver=MRAA' }}
run: |
git clone https://github.com/joan2937/pigpio.git
cd pigpio
git fetch --tags
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
git checkout $latestTag
mkdir build
cd build
cmake .. -D CMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf \
-D CMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/toolchains/armhf.cmake
make
sudo make install

- name: provide MRAA
if: ${{ matrix.config-options == '--driver=MRAA' }}
env:
Expand Down Expand Up @@ -140,8 +155,8 @@ jobs:
# usr_dir: "x86_64-linux-gnux32"
# - compiler: "i686"
# usr_dir: "i686-linux-gnu"
- compiler: "default" # github runner is hosted on a "amd64"
usr_dir: "local" # using this toolchain to test python wrapper
# - compiler: "default" # github runner is hosted on a "amd64"
# usr_dir: "local" # using this toolchain to test python wrapper
driver:
- "RPi"
- "SPIDEV"
Expand Down Expand Up @@ -217,6 +232,21 @@ jobs:
# cd WiringPi
# ./build

- name: provide pigpio
if: ${{ matrix.driver == 'RPi' || matrix.driver == 'SPIDEV' }}
run: |
git clone https://github.com/joan2937/pigpio.git
cd pigpio
git fetch --tags
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
git checkout $latestTag
mkdir build
cd build
cmake .. -D CMAKE_INSTALL_PREFIX=/usr/${{ matrix.toolchain.usr_dir }} \
-D CMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/toolchains/${{ matrix.toolchain.compiler }}.cmake
make
sudo make install

- name: create CMake build environment
run: cmake -E make_directory ${{ github.workspace }}/build

Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ else ifeq ($(DRIVER), SPIDEV)
OBJECTS+=spi.o gpio.o compatibility.o interrupt.o
else ifeq ($(DRIVER), wiringPi)
OBJECTS+=spi.o
else ifeq ($(DRIVER), pigpio)
OBJECTS+=spi.o gpio.o interrupt.o compatibility.o
endif

# make all
Expand Down
1 change: 1 addition & 0 deletions cmake/AutoConfig_RF24_DRIVER.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ set(RF24_DRIVER "UNKNOWN" CACHE STRING "override automatic configuration of RF24
find_library(LibMRAA mraa)
find_library(LibWiringPi wiringPi)
find_library(LibLittleWire littlewire-spi)
find_library(PIGPIO pigpio)
if(EXISTS /dev/spidev0.0)
set(SPIDEV_EXISTS TRUE)
else()
Expand Down
9 changes: 6 additions & 3 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -398,21 +398,24 @@ fi

case ${DRIVER} in
wiringPi)
SHARED_LINKER_LIBS+=" -pthread -lwiringPi"
SHARED_LINKER_LIBS+=" -lpigpio -lwiringPi"
CFLAGS+=" -lwiringPi"
;;
SPIDEV)
SHARED_LINKER_LIBS+=" -pthread"
SHARED_LINKER_LIBS+=" -lpigpio"
;;
RPi)
SHARED_LINKER_LIBS+=" -pthread"
SHARED_LINKER_LIBS+=" -lpigpio"
;;
MRAA)
SHARED_LINKER_LIBS+=" -lmraa"
;;
LittleWire)
SHARED_LINKER_LIBS+=" -llittlewire-spi"
;;
pigpio)
SHARED_LINKER_LIBS+=" -lpigpio"
;;
*)
die "Unsupported DRIVER: ${DRIVER}." 2
;;
Expand Down
5 changes: 4 additions & 1 deletion examples_linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ include(../cmake/AutoConfig_RF24_DRIVER.cmake)
find_library(RF24 rf24 REQUIRED)
message(STATUS "using RF24 library: ${RF24}")

# pigpio lib is linked for IRQ feature
find_library(PIGPIO pigpio)

# conditionally append "interruptConfigure" to the EXAMPLES_LIST
if("${RF24_DRIVER}" STREQUAL "MRAA" OR "${RF24_DRIVER}" STREQUAL "wiringPi")
message(STATUS "Skipping interruptConfigure.cpp example as it is incompatible with selected driver library")
Expand All @@ -41,6 +44,6 @@ foreach(example ${EXAMPLES_LIST})
# wiringPi additionally needs to link to crypt and shm_open libraries
target_link_libraries(${example} PUBLIC ${RF24} pthread ${LibWiringPi} crypt rt)
else() # not using MRAA or wiringPi drivers
target_link_libraries(${example} PUBLIC ${RF24} pthread)
target_link_libraries(${example} PUBLIC ${RF24} pthread ${PIGPIO})
endif()
endforeach()
2 changes: 2 additions & 0 deletions utility/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ if ("${RF24_DRIVER}" STREQUAL "wiringPi") # Use wiringPi
DESTINATION include/RF24/utility/${RF24_DRIVER}
)
elseif("${RF24_DRIVER}" STREQUAL "RPi") # use RPi
set(RF24_LINKED_DRIVER ${PIGPIO} PARENT_SCOPE)
set(RF24_DRIVER_SOURCES
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/bcm2835.c
Expand All @@ -39,6 +40,7 @@ elseif("${RF24_DRIVER}" STREQUAL "SPIDEV") # use SPIDEV
if(NOT SPIDEV_EXISTS)
message(WARNING "Detecting /dev/spidev0.0 failed - continuing anyway. Please make sure SPI is enabled.")
endif()
set(RF24_LINKED_DRIVER ${PIGPIO} PARENT_SCOPE)
set(RF24_DRIVER_SOURCES
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h
${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/gpio.cpp
Expand Down
210 changes: 9 additions & 201 deletions utility/RPi/interrupt.cpp
Original file line number Diff line number Diff line change
@@ -1,221 +1,29 @@
/*
Interrupts functions extruded from wiringPi library by Oitzu.

wiringPi Copyright (c) 2012 Gordon Henderson
https://projects.drogon.net/raspberry-pi/wiringpi
wiringPi is free software: GNU Lesser General Public License
see <http://www.gnu.org/licenses/>
Interrupt functions
*/

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <sys/stat.h>
#include "interrupt.h"
#include <pthread.h>

#define delay(x) bcm2835_delay(x)

static pthread_mutex_t pinMutex = PTHREAD_MUTEX_INITIALIZER;
static volatile int pinPass = -1;

pthread_t threadId[64];

// sysFds:
// Map a file descriptor from the /sys/class/gpio/gpioX/value
static int sysFds[64] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1,};

// ISR Data
static void (* isrFunctions[64])(void);

int waitForInterrupt(int pin, int mS)
{
int fd, x;
uint8_t c;
struct pollfd polls;

if ((fd = sysFds[pin]) == -1) {
return -2;
}

// Setup poll structure

polls.fd = fd;
polls.events = POLLPRI; // Urgent data!

// Wait for it ...
x = poll(&polls, 1, mS);

// Do a dummy read to clear the interrupt
// A one character read appars to be enough.
// Followed by a seek to reset it.

(void) (read(fd, &c, 1) + 1);
lseek(fd, 0, SEEK_SET);

return x;
}

int piHiPri(const int pri)
{
struct sched_param sched;

memset(&sched, 0, sizeof(sched));

if (pri > sched_get_priority_max(SCHED_RR)) {
sched.sched_priority = sched_get_priority_max(SCHED_RR);
} else {
sched.sched_priority = pri;
}

return sched_setscheduler(0, SCHED_RR, &sched);
}

void* interruptHandler(void* arg)
{
int myPin;

(void) piHiPri(55); // Only effective if we run as root

myPin = pinPass;
pinPass = -1;
#include <pigpio.h>

for (;;) {
if (waitForInterrupt(myPin, -1) > 0) {
pthread_mutex_lock(&pinMutex);
isrFunctions[myPin]();
pthread_mutex_unlock(&pinMutex);
pthread_testcancel(); //Cancel at this point if we have an cancellation request.
}
}

return NULL;
}

int attachInterrupt(int pin, int mode, void (* function)(void))
{
const char* modeS;
char fName[64];
char pinS[8];
pid_t pid;
int count, i;
char c;
int bcmGpioPin;

bcmGpioPin = pin;

if (mode != INT_EDGE_SETUP) {
/**/ if (mode == INT_EDGE_FALLING) {
modeS = "falling";
} else if (mode == INT_EDGE_RISING) {
modeS = "rising";
} else {
modeS = "both";
}

sprintf(pinS, "%d", bcmGpioPin);

if ((pid = fork()) < 0) { // Fail
return printf("wiringPiISR: fork failed: %s\n", strerror(errno));
}

if (pid == 0) // Child, exec
{
/**/ if (access("/usr/local/bin/gpio", X_OK) == 0) {
execl("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
} else if (access("/usr/bin/gpio", X_OK) == 0) {
execl("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
} else {
return printf("wiringPiISR: Can't find gpio program\n");
}
} else { // Parent, wait
wait(NULL);
}
}

if (sysFds[bcmGpioPin] == -1) {
sprintf(fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin);
if ((sysFds[bcmGpioPin] = open(fName, O_RDWR)) < 0) {
return printf("wiringPiISR: unable to open %s: %s\n", fName, strerror(errno));
}
}

ioctl(sysFds[bcmGpioPin], FIONREAD, &count);
for (i = 0; i < count; ++i) {
(void) (read(sysFds[bcmGpioPin], &c, 1) + 1);
}

isrFunctions[pin] = function;

pthread_mutex_lock(&pinMutex);
pinPass = pin;
pthread_create(&threadId[bcmGpioPin], NULL, interruptHandler, NULL);
while (pinPass != -1)
delay (1);
pthread_mutex_unlock(&pinMutex);

return 0;
gpioInitialise();
return gpioSetISRFunc(pin,mode,0,(gpioISRFunc_t)function);

}

int detachInterrupt(int pin)
{
char pinS[8];
const char* modeS = "none";
pid_t pid;

if (pthread_cancel(threadId[pin]) != 0) //Cancel the thread
{
return 0;
}

if (close(sysFds[pin]) != 0) //Close filehandle
{
return 0;
}

/* Set wiringPi to 'none' interrupt mode */

sprintf(pinS, "%d", pin);

if ((pid = fork()) < 0) { // Fail
return printf("wiringPiISR: fork failed: %s\n", strerror(errno));
}

if (pid == 0) // Child, exec
{
/**/ if (access("/usr/local/bin/gpio", X_OK) == 0) {
execl("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
} else if (access("/usr/bin/gpio", X_OK) == 0) {
execl("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char*) NULL);
return printf("wiringPiISR: execl failed: %s\n", strerror(errno));
} else {
return printf("wiringPiISR: Can't find gpio program\n");
}
} else { // Parent, wait
wait(NULL);
}

return 1;
return gpioSetISRFunc(pin,0,0,NULL);
}

void rfNoInterrupts()
{
pthread_mutex_lock(&pinMutex);

}

void rfInterrupts()
{
pthread_mutex_unlock(&pinMutex);
}

}
Loading