Skip to content

Commit

Permalink
supplement SPIDEV & RPi drivers with copy of linux/gpio.h (#49)
Browse files Browse the repository at this point in the history
* supplement SPIDEV & RPi drivers with copy of linux/gpio.h
- updates RF24 submodule to nRF24/RF24@a6eae52
- check in copy of linux/gpio.h (& exclude from clang-format checks)
- adjust root CMakeLists.txt to supplement build with linux/gpio.h (only for SPIDEV & RPi drivers)
* remove -D RF24_NO_INTERRUPT=1
* build static C++ libs then link them to py bindings
* update irq example
  - switch from RPi.GPIO to gpiod
* review examples and amend README
* group dependabot PRs for github CI actions
  • Loading branch information
2bndy5 authored Mar 28, 2024
1 parent 8a520e7 commit b293683
Show file tree
Hide file tree
Showing 27 changed files with 1,249 additions and 672 deletions.
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ updates:
directory: "/"
schedule:
interval: "weekly"
groups:
actions:
patterns:
- "*"
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ jobs:
--style=file \
--tidy-checks='-*' \
--lines-changed-only=true \
--ignore='!src|' \
--ignore='src/linux/gpio.h' \
--format-review=true \
--file-annotations=false
--file-annotations=false \
--step-summary=true
- name: C++ Linter checks failed?
if: steps.linter.outputs.checks-failed > 0
Expand Down
116 changes: 73 additions & 43 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,78 +18,108 @@ if(NOT "${RF24_LINKED_DRIVER}" STREQUAL "")
message(STATUS "Linking to utility driver '${RF24_LINKED_DRIVER}'")
endif()

################################# RF24 #############################
# suplement our copy of linux/gpio.h into SPIDEV & RPi driver sources
set(SUPPLEMENT_LINUX_GPIO_H FALSE)
if("${RF24_DRIVER}" STREQUAL "RPi" OR "${RF24_DRIVER}" STREQUAL "SPIDEV")
set(SUPPLEMENT_LINUX_GPIO_H TRUE)
message(STATUS "Supplementing ${RF24_DRIVER} driver with linux/gpio.h")
# file(COPY src/linux/gpio.h DESTINATION RF24/utility/${RF24_DRIVER}/linux)
list(APPEND RF24_DRIVER_SOURCES src/linux/gpio.h)
endif()

### Build C++ RF24 stack as shared libraries (resulting in isolated binary drivers)

################################# RF24 C++ #########################
add_library(cpp_rf24 SHARED
RF24/RF24.cpp
${RF24_DRIVER_SOURCES}
)
if(SUPPLEMENT_LINUX_GPIO_H)
target_include_directories(cpp_rf24 PUBLIC src)
endif()
target_include_directories(cpp_rf24 PUBLIC utility)
if(NOT "${RF24_LINKED_DRIVER}" STREQUAL "")
if("${RF24_DRIVER}" STREQUAL "wiringPi")
target_link_libraries(cpp_rf24 PUBLIC rt crypt ${RF24_LINKED_DRIVER})
else()
target_link_libraries(cpp_rf24 PUBLIC ${RF24_LINKED_DRIVER})
endif()
endif()
apply_flags(cpp_rf24)

################################# RF24Network C++ #########################
add_library(cpp_rf24_network SHARED
RF24Network/RF24Network.cpp
)
# don't let source look for an installed RF24 lib
target_compile_definitions(cpp_rf24_network PUBLIC USE_RF24_LIB_SRC)
target_include_directories(cpp_rf24_network PUBLIC
RF24
RF24/utility
RF24/utility/${RF24_DRIVER}
RF24Network
)
target_link_libraries(cpp_rf24_network PUBLIC cpp_rf24)
apply_flags(cpp_rf24_network)

################################# RF24Mesh C++ #########################
add_library(cpp_rf24_mesh SHARED
RF24Mesh/RF24Mesh.cpp
)
# don't let source look for an installed RF24 lib
target_compile_definitions(cpp_rf24_mesh PUBLIC USE_RF24_LIB_SRC)
target_include_directories(cpp_rf24_mesh PUBLIC
RF24
RF24/utility
RF24/utility/${RF24_DRIVER}
RF24Network
RF24Mesh
)
target_link_libraries(cpp_rf24_mesh PUBLIC cpp_rf24_network)
apply_flags(cpp_rf24_mesh)

### Build python bindings for RF24 stack and link to shared C++ lib binaries

################################# RF24 #############################
pybind11_add_module(rf24 src/pyRF24.cpp)
target_link_libraries(rf24 PUBLIC cpp_rf24)
target_include_directories(rf24 PUBLIC
RF24
RF24/utility
RF24/utility/${RF24_DRIVER}
)
target_sources(rf24 PUBLIC
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24.h
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24.cpp
${CMAKE_CURRENT_LIST_DIR}/RF24/nRF24L01.h
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24_config.h
${RF24_DRIVER_SOURCES}
)
apply_flags(rf24)

################################# RF24NETWORK #############################

pybind11_add_module(rf24_network src/pyRF24Network.cpp)
target_link_libraries(rf24_network PUBLIC cpp_rf24_network)
target_include_directories(rf24_network PUBLIC
RF24
RF24Network
RF24/utility
RF24/utility/${RF24_DRIVER}
RF24Network
)
# don't let source look for an installed RF24 lib
target_compile_definitions(rf24_network PUBLIC USE_RF24_LIB_SRC)
target_sources(rf24_network PUBLIC
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24.h
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24.cpp
${CMAKE_CURRENT_LIST_DIR}/RF24/nRF24L01.h
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24_config.h
${RF24_DRIVER_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/RF24Network/RF24Network.h
${CMAKE_CURRENT_LIST_DIR}/RF24Network/RF24Network.cpp
${CMAKE_CURRENT_LIST_DIR}/RF24Network/RF24Network_config.h
)
apply_flags(rf24_network)


################################# RF24MESH #############################

pybind11_add_module(rf24_mesh src/pyRF24Mesh.cpp)
target_link_libraries(rf24_mesh PUBLIC cpp_rf24_mesh)
target_include_directories(rf24_mesh PUBLIC
RF24
RF24Network
RF24Mesh
RF24/utility
RF24/utility/${RF24_DRIVER}
RF24Network
RF24Mesh
)
# don't let source look for an installed RF24 lib
target_compile_definitions(rf24_mesh PUBLIC USE_RF24_LIB_SRC)
target_sources(rf24_mesh PUBLIC
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24.h
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24.cpp
${CMAKE_CURRENT_LIST_DIR}/RF24/nRF24L01.h
${CMAKE_CURRENT_LIST_DIR}/RF24/RF24_config.h
${RF24_DRIVER_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/RF24Network/RF24Network.h
${CMAKE_CURRENT_LIST_DIR}/RF24Network/RF24Network.cpp
${CMAKE_CURRENT_LIST_DIR}/RF24Network/RF24Network_config.h
${CMAKE_CURRENT_LIST_DIR}/RF24Mesh/RF24Mesh.h
${CMAKE_CURRENT_LIST_DIR}/RF24Mesh/RF24Mesh.cpp
${CMAKE_CURRENT_LIST_DIR}/RF24Mesh/RF24Mesh_config.h
)
apply_flags(rf24_mesh)


################################ INSTALL RULES ####################################
# these are needed for scikit builds since the resulting .so files are copied into
# the binary distribution wheels (.whl files) for python.
install(TARGETS rf24 DESTINATION .)
install(TARGETS rf24_network DESTINATION .)
install(TARGETS rf24_mesh DESTINATION .)
install(TARGETS rf24 rf24_network rf24_mesh DESTINATION .)
install(TARGETS cpp_rf24 cpp_rf24_network cpp_rf24_mesh DESTINATION .)

# uncomment to show compiler args used in build logs
# set(CMAKE_VERBOSE_MAKEFILE ON)
7 changes: 4 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,17 @@ The IRQ pin is not typically connected, and it is only used in the interrupt_con
ultimately depends on the nature of your power supply's stability.

.. note::
Notice that RPi.GPIO (for python) is used to manage the GPIO pins on the Raspberry Pi
Notice that `gpiod <https://pypi.org/project/gpiod>`_ is used to watch the radio's IRQ pin
(exclusively during the
`interrupt_configure.py <https://pyrf24.readthedocs.io/en/latest/examples.html#interrupt-configure>`_
example).

RPi.GPIO is not required for normal usage (when not using the radio's IRQ pin).
`gpiod <https://pypi.org/project/gpiod>`_ is not required for normal usage (when not using the radio's IRQ pin).

.. code-block:: bash
sudo apt install python3-rpi.gpio
sudo apt install python3-dev
pip install gpiod
Installing from PyPI
~~~~~~~~~~~~~~~~~~~~
Expand Down
2 changes: 1 addition & 1 deletion RF24
Submodule RF24 updated 69 files
+20 −17 .github/workflows/build_linux.yml
+2 −1 .gitignore
+6 −4 CMakeLists.txt
+2 −8 Makefile
+0 −5 RF24.cpp
+0 −3 RF24.h
+3 −26 configure
+1 −0 docs/main_page.md
+31 −21 examples/InterruptConfigure/InterruptConfigure.ino
+143 −58 examples/scanner/scanner.ino
+323 −0 examples/scannerGraphic/scannerGraphic.ino
+32 −18 examples_linux/CMakeLists.txt
+1 −1 examples_linux/Makefile
+2 −0 examples_linux/Makefile.examples
+2 −0 examples_linux/acknowledgementPayloads.cpp
+2 −0 examples_linux/gettingstarted.cpp
+26 −17 examples_linux/interruptConfigure.cpp
+2 −0 examples_linux/manualAcknowledgements.cpp
+2 −0 examples_linux/multiceiverDemo.cpp
+20 −0 examples_linux/ncurses/CMakeLists.txt
+341 −0 examples_linux/ncurses/scanner_curses.cpp
+1 −1 examples_linux/readme.md
+119 −51 examples_linux/scanner.cpp
+205 −87 examples_linux/scanner.py
+2 −0 examples_linux/streamingData.cpp
+19 −5 examples_pico/interruptConfigure.cpp
+133 −52 examples_pico/scanner.cpp
+1 −10 pyRF24/setup.py
+22 −52 utility/CMakeLists.txt
+5 −14 utility/MRAA/RF24_arch_config.h
+1 −9 utility/MRAA/compatibility.cpp
+0 −3 utility/MRAA/compatibility.h
+44 −62 utility/MRAA/gpio.cpp
+19 −15 utility/MRAA/gpio.h
+0 −1 utility/MRAA/spi.h
+11 −7 utility/RPi/RF24_arch_config.h
+9 −1 utility/RPi/compatibility.cpp
+2 −3 utility/RPi/compatibility.h
+2 −3 utility/RPi/includes.h
+193 −11 utility/RPi/interrupt.cpp
+72 −33 utility/RPi/interrupt.h
+4 −8 utility/SPIDEV/RF24_arch_config.h
+11 −7 utility/SPIDEV/compatibility.cpp
+0 −3 utility/SPIDEV/compatibility.h
+147 −59 utility/SPIDEV/gpio.cpp
+41 −8 utility/SPIDEV/gpio.h
+1 −3 utility/SPIDEV/includes.h
+170 −10 utility/SPIDEV/interrupt.cpp
+47 −33 utility/SPIDEV/interrupt.h
+35 −50 utility/SPIDEV/spi.cpp
+4 −2 utility/SPIDEV/spi.h
+2 −4 utility/Template/compatibility.h
+2 −2 utility/Template/includes.h
+4 −19 utility/Template/spi.h
+6 −9 utility/pigpio/RF24_arch_config.h
+3 −7 utility/pigpio/compatibility.cpp
+5 −13 utility/pigpio/compatibility.h
+1 −2 utility/pigpio/gpio.cpp
+5 −25 utility/pigpio/gpio.h
+4 −5 utility/pigpio/includes.h
+13 −6 utility/pigpio/interrupt.cpp
+14 −37 utility/pigpio/interrupt.h
+1 −1 utility/pigpio/spi.cpp
+4 −25 utility/pigpio/spi.h
+3 −6 utility/wiringPi/RF24_arch_config.h
+2 −11 utility/wiringPi/includes.h
+14 −0 utility/wiringPi/interrupt.h
+29 −36 utility/wiringPi/spi.cpp
+18 −6 utility/wiringPi/spi.h
33 changes: 10 additions & 23 deletions cmake/using_flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
# RF24 core specific options
option(RF24_DEBUG "enable/disable debugging output for RF24 lib" OFF)

# Disabling IRQ support should be always done because
# IRQ support can be handled in python with different libs.
option(RF24_NO_INTERRUPT "disable IRQ support (dependent on pigpio)" ON)
# does not affect pigpio driver though

# RF24Network specific options
option(SERIAL_DEBUG "enable/disable debugging output for RF24Network lib" OFF)
option(SERIAL_DEBUG_MINIMAL "enable/disable minimal debugging output for RF24Network lib" OFF)
Expand Down Expand Up @@ -60,27 +55,19 @@ option(MESH_DEBUG_MINIMAL "enable/disable minimal debugging output for RF24Mesh
###############################################
# function to apply flags to applicable targets
function(apply_flags target)
# apply RF24 flags to all targets
if(RF24_NO_INTERRUPT)
target_compile_definitions(${target} PUBLIC RF24_NO_INTERRUPT)
endif()
if(RF24_DEBUG)
message(STATUS "RF24_DEBUG asserted for ${target}")
target_compile_definitions(${target} PUBLIC SERIAL_DEBUG)
# apply RF24 flags to cpp_rf24 target
if("${target}" STREQUAL "cpp_rf24")
if(RF24_DEBUG)
message(STATUS "RF24_DEBUG asserted for ${target}")
target_compile_definitions(${target} PUBLIC SERIAL_DEBUG)
endif()
endif()

# pass driver used to expose as a constant in rf24 module.
target_compile_definitions(${target} PUBLIC RF24_DRIVER="${RF24_DRIVER}")
if(NOT "${RF24_LINKED_DRIVER}" STREQUAL "")
if("${RF24_DRIVER}" STREQUAL "wiringPi")
target_link_libraries(${target} PRIVATE rt crypt ${RF24_LINKED_DRIVER})
else()
target_link_libraries(${target} PRIVATE ${RF24_LINKED_DRIVER})
endif()
endif()

# apply RF24Network flags to rf24_mesh and rf24_network targets
if("${target}" STREQUAL "rf24_network" OR "${target}" STREQUAL "rf24_mesh")
# apply RF24Network flags to cpp_rf24_network target
if("${target}" STREQUAL "cpp_rf24_network")
if(SERIAL_DEBUG)
message(STATUS "SERIAL_DEBUG asserted for ${target}")
target_compile_definitions(${target} PUBLIC SERIAL_DEBUG)
Expand Down Expand Up @@ -116,8 +103,8 @@ function(apply_flags target)
endif()
endif()

# apply RF24Mesh flags to only rf24_mesh target
if("${target}" STREQUAL "rf24_mesh")
# apply RF24Mesh flags to cpp_rf24_mesh target
if("${target}" STREQUAL "cpp_rf24_mesh")
if(MESH_NOMASTER)
message(STATUS "MESH_NOMASTER asserted for ${target}")
target_compile_definitions(${target} PUBLIC MESH_NOMASTER)
Expand Down
44 changes: 16 additions & 28 deletions examples/acknowledgement_payloads.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""
Simple example of using the library to transmit
and retrieve custom automatic acknowledgment payloads.
See documentation at https://nRF24.github.io/pyRF24
"""

import sys
import time
import argparse
from pyrf24 import RF24, RF24_PA_LOW
from pyrf24 import RF24, RF24_PA_LOW, RF24_DRIVER

print(__file__) # print example name

########### USER CONFIGURATION ###########
# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md
Expand All @@ -15,7 +17,14 @@
# their own pin numbering
# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b>
# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc..
radio = RF24(22, 0)
CSN_PIN = 0 # aka CE0 on SPI bus 0: /dev/spidev0.0
if RF24_DRIVER == "MRAA":
CE_PIN = 15 # for GPIO22
elif RF24_DRIVER == "wiringPi":
CE_PIN = 3 # for GPIO22
else:
CE_PIN = 22
radio = RF24(CE_PIN, CSN_PIN)

# using the python keyword global is bad practice. Instead we'll use a 1 item
# list to store our integer number for the payloads' counter
Expand Down Expand Up @@ -55,7 +64,7 @@
radio.open_rx_pipe(1, address[not radio_number]) # using pipe 1

# for debugging
radio.print_pretty_details()
# radio.print_pretty_details()


def master(count: int = 5): # count = 5 will only transmit 5 packets
Expand Down Expand Up @@ -154,33 +163,12 @@ def set_role():
return set_role()


print(sys.argv[0]) # print example name


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
"-r",
"--role",
type=int,
choices=range(2),
help="'1' specifies the TX role. '0' specifies the RX role.",
)
args = parser.parse_args() # parse any CLI args

try:
if args.role is None: # if not specified with CLI arg '-r'
while set_role():
pass # continue example until 'Q' is entered
elif bool(args.role): # if role was set using CLI args, run role once and exit
master()
else:
slave()
while set_role():
pass # continue example until 'Q' is entered
except KeyboardInterrupt:
print(" Keyboard Interrupt detected. Exiting...")
radio.power = False
sys.exit()
else:
print(" Run slave() on receiver\n Run master() on transmitter")
17 changes: 10 additions & 7 deletions examples/fake_ble_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""
This example uses the nRF24L01 as a 'fake' BLE Beacon
See documentation at https://nRF24.github.io/pyRF24
"""

import time
Expand All @@ -15,8 +17,15 @@
TemperatureServiceData,
)

print(__file__) # print example name

# initialize the nRF24L01 on the spi bus object as a BLE compliant radio
########### USER CONFIGURATION ###########
# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md
# Radio CE Pin, CSN Pin, SPI Speed
# CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use
# their own pin numbering
# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b>
# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc..
CSN_PIN = 0 # aka CE0 on SPI bus 0: /dev/spidev0.0
if RF24_DRIVER == "MRAA":
CE_PIN = 15 # for GPIO22
Expand All @@ -26,10 +35,6 @@
CE_PIN = 22
radio = RF24(CE_PIN, CSN_PIN)
ble = FakeBLE(radio)
# On Linux, csn value is a bit coded
# 0 = bus 0, CE0 # SPI bus 0 is enabled by default
# 10 = bus 1, CE0 # enable SPI bus 2 prior to running this
# 21 = bus 2, CE1 # enable SPI bus 1 prior to running this

if not ble.begin():
raise OSError("radio hardware not responding")
Expand Down Expand Up @@ -197,8 +202,6 @@ def set_role():
return set_role()


print(" nRF24L01 fake BLE beacon test")

if __name__ == "__main__":
try:
while set_role():
Expand Down
Loading

0 comments on commit b293683

Please sign in to comment.