Skip to content

Commit 929a5aa

Browse files
authored
refactor: set /dev/gpiochip0 as default (#1018)
resolves #1017 This also adds some info to the docs that was requested in #1017 * remove unnecessary members * make cached chip FD static
1 parent 6f3da43 commit 929a5aa

9 files changed

+69
-44
lines changed

RF24.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ class RF24
215215
*
216216
* See [Related Pages](pages.html) for device specific information
217217
*
218-
* @param _cepin The pin attached to Chip Enable on the RF module
218+
* @param _cepin The pin attached to Chip Enable on the RF module.
219+
* Review our [Linux general](rpi_general.md) doc for details about selecting pin numbers on Linux systems.
219220
* @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module.
220221
* - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI)
221222
* is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for
@@ -290,7 +291,8 @@ class RF24
290291
* @param spiBus A pointer or reference to an instantiated SPI bus object.
291292
* The `_SPI` datatype is a "wrapped" definition that will represent
292293
* various SPI implementations based on the specified platform.
293-
* @param _cepin The pin attached to Chip Enable on the RF module
294+
* @param _cepin The pin attached to Chip Enable on the RF module.
295+
* Review our [Linux general](rpi_general.md) doc for details about selecting pin numbers on Linux systems.
294296
* @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module.
295297
* - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI)
296298
* is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for the radio's CSN pin.

cspell.config.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ words:
134134
- iomanip
135135
- ITSYBITSY
136136
- Jannis
137+
- Jetson
137138
- jscrane
138139
- KBPS
139140
- Konde
@@ -142,6 +143,7 @@ words:
142143
- ldiaz
143144
- libboost
144145
- libc
146+
- libgpiod
145147
- libmaple
146148
- libncurses
147149
- librf

docs/Doxyfile

+6
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ SHOW_FILES = YES
135135

136136
SHOW_NAMESPACES = NO
137137

138+
# Don't display the ugly/complicated "tree view" side menu.
139+
# And, restore the top (simpler) navigation bar.
140+
# As of doxygen v1.13.0, these default values changed from NO to YES
141+
GENERATE_TREEVIEW = NO
142+
DISABLE_INDEX = NO
143+
138144
#---------------------------------------------------------------------------
139145
# Configuration options related to warning and progress messages
140146
#---------------------------------------------------------------------------

docs/linux_install.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ Using CMake: (See the [instructions using CMake](using_cmake.md) for more inform
2424
./install.sh
2525
```
2626

27-
@warning
27+
@warning
2828
`SPIDEV` is now always selected as the default driver because
2929
all other Linux drivers are being removed in the future.
3030
See [RF24 issue #971](https://github.com/nRF24/RF24/issues/971) for rationale.
3131

3232
It will also ask to install a python package named [pyRF24](https://github.com/nRF24/pyRF24).
33-
This is not the same as the traditionally provided python wrappers as the pyRF24 package can be
33+
This is not the same as the traditionally provided python wrappers because the pyRF24 package can be
3434
used independent of the C++ installed libraries. For more information on this newer python
3535
package, please check out [the pyRF24 documentation](https://nrf24.github.io/pyRF24/).
3636
4. Try an example from one of the libraries
@@ -76,7 +76,7 @@ See the [instructions using CMake](using_cmake.md) for more information and opti
7676
./install.sh
7777
```
7878

79-
@warning
79+
@warning
8080
`SPIDEV` is now always selected as the default driver because
8181
all other Linux drivers are being removed in the future.
8282
See [RF24 issue #971](https://github.com/nRF24/RF24/issues/971) for rationale.
@@ -115,7 +115,7 @@ See the [instructions using CMake](using_cmake.md) for more information and opti
115115
```
116116
It automatically detects device and build environment.
117117

118-
@warning
118+
@warning
119119
`SPIDEV` is now always selected as the default driver because
120120
all other Linux drivers are being removed in the future.
121121
See [RF24 issue #971](https://github.com/nRF24/RF24/issues/971) for rationale.

docs/rpi_general.md

+29-2
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,43 @@ for proper constructor to address the correct spi device at /dev/spidev\<a\>.\<b
4949
5050
Choose any GPIO output pin for radio CE pin.
5151
52+
> [!WARNING]
53+
> The pin numbers may be different for certain systems.
54+
> In this library's examples, we use the BCM pin numbers for BroadCom chips such as
55+
> those used on all Raspberry Pi models.
56+
>
57+
> For Raspberry Pi clones, such as Orange Pi or Banana Pi, defer to the pin numbers described
58+
> in their corresponding documentation/manual.
59+
>
60+
> Hint: If libgpiod is installed (not required for this library),
61+
> then you can use the included
62+
> [CLI tools shipped with libgpiod](https://libgpiod.readthedocs.io/en/latest/gpio_tools.html)
63+
> to gleam system-specific details.
64+
65+
### Linux kernel (SPIDEV driver) and the GPIO chip number
66+
67+
This RF24 library, as of v1.4.9, uses the Linux kernel's Character Device API to interface
68+
with GPIO pins (AKA "lines" in kernel docs). Previous versions used the deprecated "sys fs" interface.
69+
70+
By default, this library attempts to use pins exposed via `/dev/gpiochip0`.
71+
Some systems have multiple public-facing GPIO chips integrated (ie nVidia Jetson series).
72+
If your system exposes the desired GPIO pins via a different chip (ie `/dev/gpiochip4`), then the
73+
`RF24_LINUX_GPIO_CHIP` can be set to the correct value when compiling the library.
74+
75+
```shell
76+
cmake .. -DRF24_LINUX_GPIO_CHIP="/dev/gpiochip4"
77+
```
78+
5279
### General
5380

5481
```cpp
55-
RF24 radio(22,0);
82+
RF24 radio(22, 0);
5683
```
5784
5885
### MRAA Constructor
5986
6087
```cpp
61-
RF24 radio(15,0);
88+
RF24 radio(15, 0);
6289
```
6390

6491
See [the MRAA documentation for Raspberry Pi support](http://iotdk.intel.com/docs/master/mraa/rasppi.html)

utility/RPi/RF24_arch_config.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ typedef uint8_t rf24_gpio_pin_t;
2929

3030
#ifndef RF24_LINUX_GPIO_CHIP
3131
/**
32-
* The default GPIO chip to use. Defaults to `/dev/gpiochip4` (for RPi5).
33-
* Falls back to `/dev/gpiochip0` if this value is somehow incorrect.
32+
* The default GPIO chip to use.
33+
* Defaults to `/dev/gpiochip0`.
34+
* Define this when compiling if this value is somehow incorrect.
3435
*/
35-
#define RF24_LINUX_GPIO_CHIP "/dev/gpiochip4"
36+
#define RF24_LINUX_GPIO_CHIP "/dev/gpiochip0"
3637
#endif
3738

3839
#define PSTR(x) (x)

utility/SPIDEV/gpio.cpp

+8-16
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@ std::map<rf24_gpio_pin_t, gpio_fd> cachedPins;
2121
struct gpio_v2_line_request request;
2222
struct gpio_v2_line_values data;
2323

24+
// initialize static member.
25+
int GPIOChipCache::fd = -1;
26+
2427
void GPIOChipCache::openDevice()
2528
{
2629
if (fd < 0) {
27-
fd = open(chip, O_RDONLY);
30+
fd = open(RF24_LINUX_GPIO_CHIP, O_RDONLY);
2831
if (fd < 0) {
2932
std::string msg = "Can't open device ";
30-
msg += chip;
33+
msg += RF24_LINUX_GPIO_CHIP;
3134
msg += "; ";
3235
msg += strerror(errno);
3336
throw GPIOException(msg);
3437
return;
3538
}
3639
}
37-
chipInitialized = true;
3840
}
3941

4042
void GPIOChipCache::closeDevice()
@@ -75,31 +77,21 @@ GPIO::~GPIO()
7577

7678
void GPIO::open(rf24_gpio_pin_t port, int DDR)
7779
{
78-
try {
79-
gpioCache.openDevice();
80-
}
81-
catch (GPIOException& exc) {
82-
if (gpioCache.chipInitialized) {
83-
throw exc;
84-
return;
85-
}
86-
gpioCache.chip = "/dev/gpiochip0";
87-
gpioCache.openDevice();
88-
}
80+
gpioCache.openDevice();
8981

9082
// get chip info
9183
gpiochip_info info;
9284
memset(&info, 0, sizeof(info));
9385
int ret = ioctl(gpioCache.fd, GPIO_GET_CHIPINFO_IOCTL, &info);
9486
if (ret < 0) {
9587
std::string msg = "Could not gather info about ";
96-
msg += gpioCache.chip;
88+
msg += RF24_LINUX_GPIO_CHIP;
9789
throw GPIOException(msg);
9890
return;
9991
}
10092

10193
if (port > info.lines) {
102-
std::string msg = "pin number " + std::to_string(port) + " not available for " + gpioCache.chip;
94+
std::string msg = "pin number " + std::to_string(port) + " not available for " + RF24_LINUX_GPIO_CHIP;
10395
throw GPIOException(msg);
10496
return;
10597
}

utility/SPIDEV/gpio.h

+9-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ typedef uint16_t rf24_gpio_pin_t;
2525
* The default GPIO chip to use. Defaults to `/dev/gpiochip4` (for RPi5).
2626
* Falls back to `/dev/gpiochip0` if this value is somehow incorrect.
2727
*/
28-
#define RF24_LINUX_GPIO_CHIP "/dev/gpiochip4"
28+
#define RF24_LINUX_GPIO_CHIP "/dev/gpiochip0"
2929
#endif
3030

3131
/** Specific exception for GPIO errors */
@@ -42,9 +42,14 @@ class GPIOException : public std::runtime_error
4242
/// This struct's destructor should close any cached GPIO pin requests' file descriptors.
4343
struct GPIOChipCache
4444
{
45-
const char* chip = RF24_LINUX_GPIO_CHIP;
46-
int fd = -1;
47-
bool chipInitialized = false;
45+
/// @brief The file descriptor used to access the GPIO chip.
46+
///
47+
/// This is used to open/close pins exposed by the GPIO chip specified via
48+
/// `RF24_LINUX_GPIO_CHIP`.
49+
///
50+
/// Because this member is static, all instances (& derivative instances) of this
51+
/// struct use the same file descriptor.
52+
static int fd;
4853

4954
/// Open the File Descriptor for the GPIO chip
5055
void openDevice();

utility/SPIDEV/interrupt.cpp

+3-13
Original file line numberDiff line numberDiff line change
@@ -65,31 +65,21 @@ int attachInterrupt(rf24_gpio_pin_t pin, int mode, void (*function)(void))
6565
detachInterrupt(pin);
6666
GPIO::close(pin);
6767

68-
try {
69-
irqChipCache.openDevice();
70-
}
71-
catch (GPIOException& exc) {
72-
if (irqChipCache.chipInitialized) {
73-
throw exc;
74-
return 0;
75-
}
76-
irqChipCache.chip = "/dev/gpiochip0";
77-
irqChipCache.openDevice();
78-
}
68+
irqChipCache.openDevice();
7969

8070
// get chip info
8171
gpiochip_info info;
8272
memset(&info, 0, sizeof(info));
8373
int ret = ioctl(irqChipCache.fd, GPIO_GET_CHIPINFO_IOCTL, &info);
8474
if (ret < 0) {
8575
std::string msg = "[attachInterrupt] Could not gather info about ";
86-
msg += irqChipCache.chip;
76+
msg += RF24_LINUX_GPIO_CHIP;
8777
throw IRQException(msg);
8878
return 0;
8979
}
9080

9181
if (pin > info.lines) {
92-
std::string msg = "[attachInterrupt] pin " + std::to_string(pin) + " is not available on " + irqChipCache.chip;
82+
std::string msg = "[attachInterrupt] pin " + std::to_string(pin) + " is not available on " + RF24_LINUX_GPIO_CHIP;
9383
throw IRQException(msg);
9484
return 0;
9585
}

0 commit comments

Comments
 (0)