From b5a905b6926bf4c1d699e5d32ab7aaec4f1afe58 Mon Sep 17 00:00:00 2001 From: Raphael Krauthann <31949653+TheGarkine@users.noreply.github.com> Date: Mon, 23 Jan 2023 09:39:50 +0100 Subject: [PATCH] Reworked the utility/rp2 SPI class and removed static members (#892) * Removed 'static' keywords in SPI.h such that multiple SPI busses can be used to connect multiple Radios. Also added an example for this use-case Co-authored-by: Brendan <2bndy5@gmail.com> --- docs/pico_sdk.md | 53 +++++++++++++++++++++++++++++++++++++++++++++ utility/rp2/spi.cpp | 2 -- utility/rp2/spi.h | 16 +++++++------- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/docs/pico_sdk.md b/docs/pico_sdk.md index a1f401ce7..5d5d44eca 100644 --- a/docs/pico_sdk.md +++ b/docs/pico_sdk.md @@ -174,3 +174,56 @@ To specify the default SPI pins used at build time, you can use either: ```shell cmake --build . --config Release -DPICO_DEFAULT_SPI=0 -DPICO_DEFAULT_SPI_SCK_PIN=2 -DPICO_DEFAULT_SPI_TX_PIN=3 -DPICO_DEFAULT_SPI_RX_PIN=4 ``` + +## Using Multiple Radios + +It is possible to drive multiple nRF24L01 transceivers on a single board. To do this each radio needs dedicated digital output pins for the CE and CSN pins. + +If you want to drive each radio with a separate SPI bus, then the following example will demonstrate how to do that. + +```cpp +#include + +// Declare the pin numbers connected to the radios' CE and CSN pins (respectively) +RF24 radio0(8, 5); // first radio object +RF24 radio1(14, 13); // second radio object + +// By default, one SPI bus instance is created by the RF24 lib. We'll use this +// default instance of the `spi0` interface for our first radio, but we want a +// different SPI bus for the second radio. +// +// So, here we declare a second SPI bus instance: +SPI my_spi; // we specify the `spi1` bus interface below + +bool setupRadios() +{ + // Initialize the first radio using the default SPI instance + if (!radio0.begin()) { + printf("Radio0 hardware is not responding!\n"); + return false; + } + // first radio object initialized successfully + + // specify the the second SPI bus interface and corresponding GPIO pins + my_spi.begin(spi1, 10, 11, 12); // spi1 bus, SCK, TX, RX + if (!radio1.begin(&my_spi)) { + printf("Radio1 hardware is not responding!\n"); + return false; + } + // second radio object initialized successfully + + return true; +} + +int main() +{ + stdio_init_all(); // init necessary IO for the RP2040 + + while (!setupRadios()) { // if either radioX.begin() failed + sleep_ms(1000); // add 1 second delay for console readability + // hold program in infinite attempts to initialize the radios + } + + // continue with program as normal ... +} +``` diff --git a/utility/rp2/spi.cpp b/utility/rp2/spi.cpp index f60945198..f3e88d0f9 100644 --- a/utility/rp2/spi.cpp +++ b/utility/rp2/spi.cpp @@ -1,7 +1,5 @@ #include "spi.h" -spi_inst_t* SPI::_hw_id; - SPI::SPI() { } diff --git a/utility/rp2/spi.h b/utility/rp2/spi.h index 2339b928f..e6b3f420d 100644 --- a/utility/rp2/spi.h +++ b/utility/rp2/spi.h @@ -33,7 +33,7 @@ class SPI * @see begin(spi_inst_t, uint8_t, uint8_t, uint8_t) for using other pins as * your SPI bus. */ - static void begin(spi_inst_t* hw_id); + void begin(spi_inst_t* hw_id); /** * Start SPI @@ -47,24 +47,24 @@ class SPI * @see The [Pico SDK has a chart of applicable pins](https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf#%5B%7B%22num%22%3A106%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C115%2C377.118%2Cnull%5D) * that can be used for hardware driven SPI transactions. */ - static void begin(spi_inst_t* hw_id, uint8_t _sck, uint8_t _tx, uint8_t _rx); + void begin(spi_inst_t* hw_id, uint8_t _sck, uint8_t _tx, uint8_t _rx); - static uint8_t transfer(uint8_t tx_); + uint8_t transfer(uint8_t tx_); - static void transfernb(const uint8_t* tbuf, uint8_t* rbuf, uint32_t len); + void transfernb(const uint8_t* tbuf, uint8_t* rbuf, uint32_t len); - static void transfern(const uint8_t* buf, uint32_t len); + void transfern(const uint8_t* buf, uint32_t len); - static void beginTransaction(uint32_t _spi_speed); + void beginTransaction(uint32_t _spi_speed); /** deinit the SPI bus (using hw_id passed to begin()) */ - static void endTransaction(); + void endTransaction(); virtual ~SPI(); private: /** the ID of the hardware driven SPI bus */ - static spi_inst_t* _hw_id; + spi_inst_t* _hw_id; }; #endif // RF24_UTILITY_RP2_SPI_H_