nRF24 / RF24

OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
https://nrf24.github.io/RF24
GNU General Public License v2.0
2.21k stars 1.02k forks source link

Connecting an NRF24L01 module to a 2nd SPI on a samd21g18 #755

Closed ex-caliper closed 3 years ago

ex-caliper commented 3 years ago

Hi,

Having previously created a small network of NRF24L01 modules with Arduino Uno’s, I now have a need increase capacity in the master device. Consequently, I now have a custom breakout board with a samd21g18 containing an Arduino Zero bootloader.

With the default SPI occupied, I am trying to connect the NRF24L01 module to a 2nd SPI and like most I have studied the Adafruit and Sparkfun tutorials on how to create a 2nd SPI. https://learn.sparkfun.com/tutorials/adding-more-sercom-ports-for-samd-boards/introduction

Hence, I created an SPIClass mySPI (&sercom1, 11, 12, 10, SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0);

However, where I am lost is how to communicate with the NRF24L01 device on this 2nd SPI. I cannot even get the device to work on the default SPI.

How do I initialise the device, is this done by using the mySPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)) and further commands entered through SPI.transfer?

Has anyone successfully connected the module to a samd21g18, either by the default SPI or more interestingly via a 2nd SPI?

Any information would be greatly appreciated, thanks in advance.

2bndy5 commented 3 years ago

Hope this helps:

I think this is another reason to let begin() take an SPI object reference.

2bndy5 commented 3 years ago

I have it correctly working on a QtPy (Seeed Xiao clone) that's running on a ATSAMD21E18. I also had success on a Adafruit Feather running on a ATSAMD21G18. Just don't expect radio.printDetails() to work because of something the Arduino SAMD core does for printf() (that's a separate issue).

ex-caliper commented 3 years ago

Thankful to @szerwi for his reply, however this seems to be only applicable to ESP32's SPI.cpp https://github.com/nRF24/RF24/issues/722 and unfortunately not skilled enough to cross reference to samd21g18. @2bndy5, thank you for previous information. You say you had success with Adafruit Feather running on a ATSAMD21G18, did you use the SPI Legacy header, i.e. MOSI(PB10), MISO(PA12) and SCK(PB11) CE & CS to any. Also did you have to insert all of those in the RF24 radio constructor, whereas normally with a default SPI, only CE and CS are required. RF24 radio(CE, CS) Still having difficulty getting the module to work even with the default SPI, having parked the idea of getting it to run on a 2nd SPI at the moment and getting back to basics. Is there a simple sketch you could point me to please.

2bndy5 commented 3 years ago

did you use the SPI Legacy header, i.e. MOSI(PB10), MISO(PA12) and SCK(PB11) CE & CS to any

Nope. Not sure what that even is off-hand

Also did you have to insert all of those in the RF24 radio constructor, whereas normally with a default SPI, only CE and CS are required. RF24 radio(CE, CS)

Nope. You might beware what SparkFun says the library constructor can/cannot take as parameters. Check Lib docs if not sure.

TBH, I started developing the new examples on the Adafruit Feather M0 Express ("Express" means that there's extra storage memory on a different SPI bus), so the examples' code is all I need to get the library working on the default spi bus (I remember having to change the CE & CSN pins to RF24 radio(5, 6)).

Changing to a secondary SPI bus when a board isn't using the Linux SPIDEV driver is a more popular problem lately.

ex-caliper commented 3 years ago

@2bndy5 With regard to SPI Legacy header, apologies rubbish diagram, this is the ICSP. After dismantling the breadboard and re-wiring it, I can now confirm with you that running an nRF24L01 module with an MSP2807(ILI9341) tft on a samd21g18 default SPI will work. I have no idea why it didn't work in the first place. For those with a simple breakout board: MOSI(PB10), MISO(PA12), SCK(PB11) Note: MISO not required to tft. In my case, made the DC, CS and RESET pins of the tft, and CE, CSN pins of the nRF24L01 high in setup. e.g digitalWrite(CS, HIGH); to avoid contention. 2nd SPI on samd21g18, still work in progress..

2bndy5 commented 3 years ago

Oh I didn't know you were working with a TFT as well (sounds like a ST7789). You should be able to use both devices on the same bus as long as your TFT has a CS pin.

2bndy5 commented 3 years ago

@ex-caliper I'm working on this feature... I think its ready for testing (if you want to try out). The RF24 repo's overload-begin branch has the changes. Thanks to your tip about the Sparkfun tutorial, I've added example source code specific for the ATSAMD21

2bndy5 commented 3 years ago

I've looking to test my solution (links in comment above), but it depends on the original arduino core. I cannot test the 2nd spi bus on my Feather M0 because it already uses SERCOM4 for the default SPI and uses another SERCOM2 for the built-in SPI flash storage. I have other M0 based boards, but they're tiny form factors (qt py & trinket M0). Sso they don't have the necessary pins broken out on board.

@ex-caliper Are you still trying to achieve this? I'd like to have my solution tested before merging into main for release.

ex-caliper commented 3 years ago

@2bndy5 FYI, I connected the default SPI to the nRF24 and used the 2nd SPI to drive an ILI9341 display with the samd21g18. This satisfied my needs but never managed to wire it the other way round. However, one observation, it was important to check the order of arguments in the target device. e.g. for the ILI9341, see below:

//tft defines..
#define tft_DC 0 //PA11
#define tft_CS 3 //PA09
#define tft_RESET 1 //PA10
//2nd SPI
SPIClass mySPI (&sercom1, 11, 12, 10, SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0);
//instantiate objects -----------------------------------------------------------------------
Adafruit_ILI9341 tft = Adafruit_ILI9341(&mySPI, tft_DC,tft_CS,tft_RESET);
/*
 * Note the order of arguments in the above is important,
 * normally the CS goes before the DC but this 2nd SPI requires
 * it to go the other way round. See line 124 of Adafruit_ILI9341.cpp
 */
//rf24..
#define rf24_CE 6      //PA20=D6, chip enable..
#define rf24_CS 7   //PA21=D7, chip select..
RF24 radio(rf24_CE, rf24_CS);

Thanks for your work on this.
Regards..

2bndy5 commented 3 years ago

ok I'm glad you work things out.

I will comment out the example snippet I put together for the docs until I can get it verified.