-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[Request] Support for RPi Pico #727
Comments
Last I checked, we were still waiting for the Arduino RP2040 core to get finished (RP2040 has its own C++ SDK that Arduino folks had to use to to extend support for the IDE). The RP2040 exposes multiple hardware SPI buses, so we may have to chew on that a bit. |
Yea I don't necessarily need to use the Arduino IDE for this. Or is this library written in such a way that it utilizes Arduino IDE build tool components or api? As you said it seems easy enough to access the RP2040 hardware SPI bus so would it be as easy as adapting the RF24 library to the RP2040 SPI access syntax? Or maybe I am missing something big. |
I was thinking this library wouldn't need to change much if we rely on the Arduino core for RP2040. If you want to add native platform support you could have a look at the docs about porting RF24 library to new platforms |
@mateo4778 Have made progress on this? Or have you also decided to wait for the official Arduino Core to be published? I ask because I'm currently working on allowing non-primary SPI buses to be specified for the RF24 lib, but this means abstracting the SPI bus object's datatype (to use as a pointer) instead of directly using an instantiated singleton object... |
Hi, I've started working on this. Current status: master...kripton:rpi-pico I do have one nRF24L01+ attached. I'm using I cannot say that I've proven this to work since today I just achieved the current status with one nRF24 module. There hasn't been yet a second module to receive/reply the packages. But I've attached a logic sniffer to the SPI bus and the initialization and sending (one packet each second) look fine in pulseview (using the integrated SPI and nRF24L01+ protocol decoders). The code isn't yet beautiful or optimized and contains debugging And of course, thank you all for providing this awesome library. I can't wait to have multiple RPi Picos working with RF24Mesh :D |
the /configure bash script does auto detection of current platform, then copies the appropriate includes.h into the repo root folder. I actually had a thought about trying to detect the SDK at compile time (not during #if defined (PICO_SDK_VERSION_MAJOR)
#include "utility/rp2040/includes.h"
#endif There might be a better macro to use for this like |
Ah, right, in the configure script. I didn't look there since as you correctly pointed out, the cmake based Pico projects compile all libraries and the SDK itself together. So I basically added the RF24 lib as a git submodule to the project. |
@kripton I've added your fork to my local clone's remotes, and I'm still reading through the SDK docs... You might see a PR from me for your fork. Also, I recently got a Feather RP2040 from Adafruit, so hopefully I'll also be able to do some testing 🤞🏼. Although, I don't have a fancy oscilloscope to look at the SPI pulses (yet). Thank you for taking the lead on this. BTW, we're also trying to upgrade to CMake (#676) , but I'm not sure how useful that would be yet (concerning the Pico SDK). |
@kripton could you put a copy of the example your working with in a "examples_pico" folder (kinda like we have a "examples_linux" folder) on your fork? I just want to see the full breadth of your work so far. My hope is that we could use the Linux examples also for the RP2xxx if I trade all my The SDK comes with board definitions for all the popular variants using the RP2040 chip. Targeting a board was made freaking easy using
These points are just what I've got spinning in my head, and I wanted to jot them down somewhere (so you're not blindsided by a PR from me). This SDK & chip are soooo promising!! 😍 I'll probably start a how-to doc for this lib when I understand everything you did to get the example code compiled. |
Oh wow, you're faster than I thought :) I was also working on this to have the conditional include in Yes, I did see your work on the I agree that switching RF24 to cmake would be desirable but it probably won't make much difference when using it with a rp2040-based board. Where we could take a look is how to make RF24 compatible with the
Yes, defining the SPI pins via overload definitely makes sense. Honestly, I don't know that the default pins of SPI0 are. I assume that GPIO0 and GPIO1 are UART by default, even though they also support SPI0. Sure, the SPI changes you are proposing all make sense to me. SPI is quite new to me, I've rather used I2C in the past.
Great, I also prefer early any open communication :) Agreed, the rp2040 is amazing (especially the PIOs) and also with a very good price point. Awesome, having an easy and well documented solution to interface with nRF24-radios would be perfect! |
I pushed my latest changes to my RF24-branch and to https://github.com/kripton/rp2040-dongle/tree/kripton-rf24. Now, the |
Great that you also ordered a RP2040-based board 🎉 |
I just had an idea that might ease testing: Use Github actions to build the examples' executable binaries against the Pico SDK (for all boards defined in the SDK) and save the build artifacts (*.elf, *.uf2) on success. This would help others that don't have the development environment setup locally but want to quickly test this library's examples on their RP2040-based boards! |
Just found out that someone wrote an unofficial ArduinoCore that uses the Pico SDK. Although, I haven't tried it... |
@kripton I just created an untested branch called rp2xxx based on your work. Because you aren't using the Pico board's default SPI0 pins, the code you are running will need some modification about which pins are used by the SPI bus. The SPI frequency should now be specified from the RF24 c'tor: RF24 radio(28, 5, 250000); // default frequency is 10000000 Based on the pin numbers your code currently uses, the modification can be either 1 of 2 ways:
Questions & Notes
|
Wow, amaging work! I needed to do some fixes to get it compile (kripton@1f40cb7) but well done!
I tried that. gcc warned me that the values are redefined but SPI comms to the radio didn't work. Also nothing SPI was in the logic analyzer.
That worked. SPI communication took place and raduo was detected (at 10MHz SPI).
Yep, that was before I attached the logic analyzer and didn't know why it failed. Probably bad cabling. By now, the command succeeds on the first call.
Both true. With my old code, it didn't do transactions at all. With your code, it does. Looks nice in pulseview as well :)
Of course that's okay. This is why we develop Open Source: so others can also profit from what we do :)
Perfectly fine. So while the code compiles, detects the module just fines and queses payloads for transmitting (looks good to my unexperienced eyes in pulseview as well), the packets are not received by an Arduino Mega running the "getting started" example. Took me a while to realize why the radio module was not detected on the Arduino: The mega has SPI on Pins 50, 51 and 52. Then, radio module wqs detected just fine but no RX reported. Next step: Have two Arduinos with the example to proof RX is working on the first place. It's a pity my RTL SDRs don't tune up to 2400MHz :( |
The gettingStarted example had the payload size set to something different than 16 (actually set to 4 IIRC). need to make this setting match Option 2 is from the overload-begin branch, so I'm glad that worked. Option 1 was from reading the SDK docs, but maybe cmake's include order would be detrimental there (evident by the gcc warning). I'll grab your fixes into upstream before continuing. Thanks for being patient with my rookie |
Just a short status update so you know where I stand:
Yes, I assumed that and matched payloadsize, channel and datarate from the However, I tried the I've also tried to get the https://github.com/BastilleResearch/mousejack / https://github.com/BastilleResearch/nrf-research-firmware running on my CrazyRadio PA dongle (nRF24LU1+). It could then be used as a scanner + sniffer. The code seems to work after some Python-3-updating (BastilleResearch/nrf-research-firmware#28). The scanner also displays few frames and the payload looks what I would expect to be sent by the rf2040-dongle. Sadly, not nearly as much frames as expected are displayed.
I've retried Option 1 (re-#define the default SPI0 pins) with the defines after the #include but it still doesn't work. Sure, no problems about the coding woes. Most of them were easy fixes. Basically all but the missing #defines. That required some more code reading than expected. Have you already been able to test your code on your Adafruit feather powered by the rp2040? |
TBH, I took a break to return some focus to our RF24Log lib (we're trying to replace the limited I have been focusing more on porting the
This seems like standard troubleshooting. My usual questions to help people assess the problem would be:
Both questions are concerned with power supply stability because If you're running the same code on both MCUs driving the radios, then its probably a power supply issue.
So I see you read the COMMON_ISSUES.md file about "settings the must match", but there is other advice below that focuses on capacitors and PA/LNA modules. |
It may be better to do this on the CLI:
|
Looks like the RPi Pico board uses a RT6150B-33GQW (rated for 800mA nominal output) to regulate the USB voltage (VBus) down to 3.3V. I soldiered the header pins to my Feather RP2040 and used the USB voltage to power my adapter board (which independently regulates 5V to 3.3V with inherent capacitors) for the nRF24L01. At first there was no power being delivered, but I think that was a wiring issue because I moved wires around and it delivered power from USB. Initially, I tried CircuitPython firmware v6.2.0 (released yesterday) with my circuitpython_nrf24l01 library and I was able to run the gettingStarted.ino sketch on an Arduino Nano to successfully communicate with my lib's simple_test.py example 👍🏼 I intentionally wrote them to be compatible with each other (excluding library default differences like Next, I'll try the rp2xx branch, but I want to write a gettingStarted.cpp example to compile with CMake first... Mainly to learn about using CMake but mostly to reduce the program running on the RP2040 to minimal tasks (I'm not sure what else is going on with your rpdongle project). ps. @kripton Does DMX stand for Digital muxer/ing (assuming it has nothing to do with the musician)? Your project's readme never explains what DMX stands for. Coming from an english tutor background its good to know your audience but bad to assume what your audience knows. |
Don't worry :) Working on a good common logging library is also worth a ton. Thank you :)
Cool. Didn't yet care too much around the interrupts on the Pico. I do have some sample code running that works with interrupts to shove data via DMA to the PIO. Yeah, that's (stdout either via hardware UART or USB) a thing that the Pico-SDK makes really easy. Just compare https://github.com/raspberrypi/pico-examples/tree/master/hello_world/serial against https://github.com/raspberrypi/pico-examples/tree/master/hello_world/usb. The https://github.com/OpenLightingProject/rp2040-dongle code needs a bit more stuff copied from the SDK since it's using custom USB identifiers and interfaces. Yep, thanks for the lead regarding entering the bootloader 👍 Actually, in the SDK there is a specific command for that: https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf#%5B%7B%22num%22%3A228%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C115%2C167.598%2Cnull%5D (function
Indeed, I also read a lot on that lately. Answers:
In the meantime (yesterday) I already ordered the nRF24-adapter boards so I can power the modules with 5V. They didn't yet arrive. Will you be writing a getting-started example for the rp2040 or shall I start? Just want to avoid the work being done twice in case you are already at it.
The Pico datasheet says that it should be safe to draw 300mA from the board's regulator: https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf, chapter 2.1: "3V3 is the main 3.3V supply to RP2040 and its I/O, generated by the on-board SMPS. This pin can be used to powerexternal circuitry (maximum output current will depend on RP2040 load and VSYS voltage, it is recommended to keepthe load on this pin less than 300mA)."
Great to hear. Yes, the rp2040-dongle does quite a bit besides RF already and it's planned to do a lot more ;)
Right, DMX is not about the musician. It's about https://en.wikipedia.org/wiki/DMX512 (so You are right that the README should explain this, I will add it the coming days. Main reason it's not there is that the repo is in the context of https://github.com/OpenLightingProject / https://www.openlighting.org/. That makes it clear to people used to such things what it's about. But I fully agree that the repo itself should at least mention it. |
That's f***in awesome!!
Good find! I don't foresee a problem with the PA/LNA modules under a 300mA restriction.
Actually I put together a gettingStarted example, but got stumped on the CMake process... I'll commit what I have to rp2xxx branch. Furthermore, in writing the example specifically for the Pico SDK, I decided to try to stick with functions native to the SDK. ie. using
What you describe sounds like an interesting project. And the nRF24Lxx is a commonly used transceiver in many manufactured solutions; I found that my Steam Controller uses a nRF24LU1 in its receiving dongle as does all Logitech unifying receiver dongles (though they switched to an even cheaper knock-off from Texas Instruments -- OTA compatible -- a few years ago). |
I'm stumped; There are 2 problematic examplesmanualAck exampleWhile the TX role works perfectly, I tried looking into why
IRQ exampleThis one is always difficult to debug because it happens so freaking fast! Also there are usually stipulations about what a MCU can do during an ISR callback (I'm guessing the RP2040 has trouble accessing the USB serial connection during an ISR function).
I'd post output results, but this post is already long and the description above is more accurate than the output can show. Its worth noting that the ISR callback function's parameters are receiving
for a FALLING event on the IRQ pin |
Yeah, it probably requires setting a variable and using that variable to print the message later in the main loop. |
I'm using a volatile bool to hold the main loop while expecting an IRQ event, and a iterator for traversing the predefined payloads. So, I think I can revise the example to take most of the It's a little strange because the Pico SDK example (for IRQ callback) does nothing but print the event and pin in the ISR. Maybe the |
I just bought a QtPy 2040 😍 from adafruit (I love the form factor of their QtPy board which are basically clones of the Seeeduino Xiao). I also bought some extra SWD headers, so maybe I can debug these examples properly (I seem to have lost the other SWD headers I had). |
Oh, that sounds great! Maybe I should also order some other rp2040-based boards besides my Picos. Today waa just soldering time for me since my PCBs arrived <3. So, unfortunately still no time to test the examples :( |
Again, no big testing session today, but a PR for the howto document: #761 About the Qt Py: Shipping to Germany from adafruit.com directly is way too expensive and the European distributors don't yet have Adafruit's rp2040-based boards :( |
Left a review for that PR... Sorry to hear about shipping to Germany; that's a bummer. I also always choose the cheapest shipping (I'm usually not in a rush). |
I think that soft SPI can be implemented based on the pico-examples/pio/spi/ code. This is officially the 3rd longest thread in the history of this repo. We can keep going for the gold (by surpassing 122 comments) or I was thinking of creating a github project (basically a Kanban board) and subsequent issues to make it easier for others to follow up/along. Oops, @Avamander I can't create a github project (on upstream or at org level) because I lack the privileges. |
@2bndy5, if it's about things related to RF24, RF24's Kanban board could be enabled. |
Well this issue is currently colliding with the CMake issue, and kripton is looking into RF24Network and RF24Mesh for Pico SDK support (which will also need a CMake implementation). And then there will be that automated install script the TMRh20 hosts in TMRh20.github.io repo that will need adjusting... Basically we're beginning to polish this issue, but doing so will entail solving other issues (some of which haven't been created yet). |
Regarding SoftSPI and a task board: I would personally prefer to release the rp2xxxx-support "quite soon" with the features currently available and implement additional stuff (such as SoftSPI) later. How that work is then tracked (via a new issue or some kind of Kanban-board) is up to you ;) I'm not sure if the current implementation collides with the CMake-implementation proposed in #676 . I've seen that you pinged me there. The work indeed looks interesting and well done but my cmake-skills are too basic to actually judge it. I might try it on my Pis once. CMake for RF24Network and RF24Mesh is actually done: https://github.com/kripton/RF24Network/blob/603c3af7c19db0b4b8eeb804c24594aa78891b01/CMakeLists.txt and https://github.com/kripton/RF24Mesh/blob/0b041cb0a4c79ed15c6b37e26fea7daa26486d10/CMakeLists.txt. However, if cmake-support should be added to those as well (which I would assume), that might collide as well. That's the main reason I didn't yet raise them as PR. I can of course and we can discuss that in those repos then. |
The rp2xxx branch declares RF24 as an INTERFACE lib while #676 proposal declares RF24 as a STATIC lib. The main difference is that an INTERFACE lib needs all the necessary files explicitly named for CMake (STATIC libs don't require this). My initial thought is that we should use the Its worth saying that (I think) RF24 as an INTERFACE lib would suite the Pico SDK build paradigm (because all Pico SDK libs are INTERFACE libs), and only 1 program will be using the RF24 lib (on the RP2040 based boards). But to build on Linux, RF24 (I think) should be a STATIC lib that's built for the user-specified or automatically defaulted Linux driver (
Personally, I think this modification should be PR'd into their respective repos before calling Pico SDK support complete (or at least a stable foundation). If RF24 gets outfitted with CMake (for building on Linux or Pico SDK), then all other Linux-applicable RF24* libs should get the same treatment. With the current modification proposed by @kripton for RF24Mesh & RF24Network, CMake will only work for the Pico SDK, and the current Makefile will still work as it always has.
I still haven't fleshed out the manACK & IRQ examples' problems. However, you're right; we could keep the current build system in place for Linux and patch in CMake for Linux later. I imagine the CMake implementation for Linux would nullify/break using the current RF24/Makefile and RF24/configure files. I just don't want people to assume (since we're using CMake for the Pico SDK) that CMake would also work for Linux builds. However, if we stagger the release of CMake integration, then we might attract other CMake aficionados to help realize the CMake implementation for Linux builds. I have ulterior motives for wanting a CMake implementation for Linux builds (see this comment). |
Thanks, that were some very good explanations. I do completely understand and support migrating the current build system to CMake. And I also understand and support that on "standard" Linux, a shared library will be the result while for the Pico-sdk, it will be an INTERFACE library. There are two points we could check to know for which target we are building (deciding between pico-sdk and other build systems). I currently don't know how Android is handled by cmake but I will check the CMake files at https://github.com/AndruePeters/RF24/tree/use-cmake to understand.
I will try to implement the second case on top of https://github.com/AndruePeters/RF24/tree/use-cmake this evening. Will keep you updated and hoping to crack the 122 comments soon :D |
Done :D What I did:
GitHub-Action results look good to me: I haven't tested the build results yet but would be surprised if that broke anything. Comments in the CMakeLists files could be nicer but all relevant docs should still be valid. |
FYI, the Linux build action still employs the configure & Makefile system (not the CMake system). @kripton This an interesting solution, and I'm ok with it (because if it works then it works). Its worth saying that I don't have any idea about CMake conventional standards. Every time you do something with CMake, I'm reminded how little I know about CMake 😆 . |
Ah, okay, I see. This is how far I get with building it locally with the merged cmake-files:
So I assume it's still working as good as in the "use-cmake"-branch without the pico-sdk compatibility. Nice that you would approve that :) Now the only things left is getting the cmake-support merged and the interrupt examples (didn't yet have a closer look at them)? Yeah, I also don't know much about cmake. Never actually used it before. Learning as we go, but it's fun and cmake looks quite flexible and powerful 👍 |
yep I noticed this line in examples_pico/CMakeLists.txt
I'm not sure this is needed as it is never referenced again. If it is needed then it should probably be
I think this line is a relic from one of my commits... |
It might be that this is not needed, since we loop over the examples further down. However, it might be that the |
It was needed because the top-level CmakeLists.txt didn't declare a |
Narrowed down the ISR problem(s) with the IRQ example:
Thanks to @kripton's lead, I also added the ability to reboot to bootloader when 'b' oor 'B' is pressed (during all examples). I went as far setting Thus I've disabled triggering the ISR (via radio API - not via Pico SDK) during the RX role IRQ example. The TX role in the IRQ example works [almost] like a charm now. |
just a quick update here: the rp2xxx branch is almost ready for a PR to main, but
|
Thanks for the update! I will rebase those branches on the latest master's (since the conditional defines have been merged) and modify the CMake-files to match what we have in the RF24 library. |
PRs are here: |
I added PicoSDK CI workflows to the RF24Network & RF24Mesh libs (on their respective CMake-4-Linux branches). These workflows only build 2 examples for each lib (examples' src code should be adjusted to use I have been cleaning up RF24Network quite a bit lately (while porting Network/Mesh to pure python). And now I'm off to making new python wrappers with pybind11 (pip-installable) to realize my ulterior motive for wanting CMake in these libs 😈 |
Has anyone tried using this library with the new Raspberry Pi Pico and its new RP2040 chip? It seems like it should be easy, but since I have only personally used the RF24 library inside the Arduino environment I am not sure what I need to do to integrate this library into a separate C/C++ project or what type of dependencies are needed etc.
Any advice or comments on how I would go about trying to get this working would be much appreciated.
The text was updated successfully, but these errors were encountered: