NRF24L01+ revisited and other library issues
RS_Jim Posts: 1,713
edited 2023-02-25 23:40 in Propeller 2
@AVISA242 created a driver for this transceiver in Spin & Spin2. I was able to successfully create a working system for P1, but now I want to move on to P2. One of the files is a core.con.boardcfg.p2eval... I am attempting to reconfigure this file to work with the KISS eval series of boards that utilize a 25MHz xtal, not a 20Mhz. I don't understand is clock settings for the P2eval nor do I understand the reasoning behind the 168_000_000 clock freq for the board.
Any help in this would be much appreciated. Thanks!
There is a constant in that file that defines the xtal freq as well as one that defines a default clock freq...they of course don't have to be used. I chose the settings I chose because at the time, I think they were the max "normal" operating configuration (though it should be 160MHz, not 168MHz).
All the top level object/application does is use the config file object to provide the constants for the clock settings, as well as I/O pin definitions for any peripherals the board might have (for ex., the LEDs).
EDIT: BTW, the @ tag will only notify a forum member if you use their forum alias/handle. I don't think there's any way to map it to a real name, if the user's profile has it set...
I had dificulty in compiling the P2 code because of a missing var in the spi file. (_cpol) which I added to the file. Now that I have gotten it to compile, I am not getting the NRF to start. I will have to attach my code from my computer as I am writing this on the iPad.
edit: zip file attached
I have no idea what the NRF24L01 does nor do I ever have seen any code for it. But the usual way to get almost any program running on the KISS board that was originally designed for a 20MHz crystal is to simply add the line
to the CON section of the main object. If it's written in Spin2 you don't have to care about the details of how to set up the PLL. The Spin2 interpreter takes the xtl (PLL input) and clk (PLL output) frequencies and automatically calculates the required multiplier and divider factors.
Only if the software changes the clock frequency on the fly with HUBSET commands you have to adjust those manually.
Yes, if you don't specify what the crystal frequency is, the compilers will all incorrectly assume 20 MHz.
The NRF24L01+ is a wireless transceiver designed to interface through SPI serial. From the original code the _xtlfreq has been entered as 25_000_000 and the CLK_FREQ set at 200_000_000. I haven't tried taking the CLK_FREQ back to 160_000 so I guess I will try that next.
Just to verify a few things:
Does the serial terminal start successfully? (asking because of the questions about the clock setup above, and also in your app you have a comment that says 'the following serial code to be commented out after terminal seral test successful')
When you say the nRF24 doesn't start, do you mean your app shows the message 'start NRF failed' per your Setup() method? If this is the case: does your modified nRF24 driver still return the cogid+1 of the running cog? My original driver is written to return the same as the parent cog (e SPI engine doesn't consume an additional one), but it still needs to return something nonzero to be recognized as a successful startup.
If that's still written the same way, and you've confirmed it returns the cogid, then is your modified driver based on a new enough version of mine that checks the default pipe 0 address? If so, that also needs to pass validation (it's just to make sure it's actually connected to a real nRF24, since there's no device ID register in the chip)
Start with that and let me know where you end up.
Also, I feel I should clarify what I meant in the above post: I just meant you don't need to use the board setup object (core.con.boardcfg...) to provide the clock settings; I didn't mean that they don't have to be defined somehow
Hi Jessie, thanks for the reply.
Yes the serial terminal is working. I patched in some code to make certain that my system for setting up ports on the 8 pin boundries was working correctly by printing out the pin nnumbers that actually used in the setup routine. I had made a modification using ifnot in the call to setup so that I could have the P2 start and run without the serial terminal. That worked on the P1 version. The only other modification that I have made to the driver is to add the _cpol to the vars list of the SPI spin2 object because the compiler could not find it and would stop compiling. That brings up a point, this is being edited and compiled by flexprop on a Linux Mint v20 computer (eric smiths work) I wonder if, because it is being translated and compiled in PASM if the timing is way off. I will have to go check out what is on gethub to see if there are any SPI drivers written for smart pins (or written in PASM) that could be substituted. The only other change I have made is to substitute COPI for MOSI and CIPO for MISO in labels. I do think that I will delete the cfg part as the clock is handled in the CON section and the difference between the two boards is the presence of the sd card. If I am compiling for KISS0001, I can add a CON block for the sd card. I will have to do some thinking to figure out if a cogid is being returned.
I develop solely on Linux using flexprop as well, so there should be no difference in code timing on yours vs mine.
It might be worth trying one of the example apps that ship with my nrf24 driver, just to see that you can in fact communicate with it. By the looks of the demo code you've modified, I think you probably have a pretty old revision, so for testing purposes, the most recent commit is probably quickest. Within the past year, I've tried to pare down the demo apps to a minimum of code to get up and running. Not sure if the rev you have has them, but I also added preset settings methods for the different speeds, in tx/rx variants, so that you don't have to manually call a whole bunch of methods just to get started.
Thanks for updating me on your development environment, glad to hear that it is Linux. The fact that you use flexprop eliminates a bunch of possible variables to chase. I will print out the latest TX demo and compare it with my code to see what I can delete/change to simplify. My code was built from your demo app using cut and paste. I tried to compile the latest xmit demo code from your web site, but had checksum errors. I will try it out with real pin numbers not my fancy redirect. Have you tried to connect to the NRF using a 200MHz clock? With the Kiss eval board and a lot of available apps at 200, I have settled upon that as a system clock speed. With a 25 MHz xtal, achieving a clock of 160MHz is not easy. If you can test your demo code at 200 I would like to hear the results. I know I trashed 1 NRF by connecting it to +5 not 3.3. I am going to try using pins 6 and 7 as ground and power for the NRF keeping all other apps off the pin group. That way I avoid the problem of picking up the +5
Replaced the hard drive on this laptop with an SSD and literally extended my battery up time by hours! May try to talk wife into a new HP laptop from Walmart on black Friday, comes with win10 and free upgrade to 11. I would promptly partition the hard drive(SSD) so that I could put Linux on it. Only want Windoz when I need to run something that just not available for Linux. Linux boots in 35 seconds with SSD as opposed to nearly 2 minutes with orig hard drive.
Hi Jim...a good question, and something I should test more now that you bring it up. I've just now tested a P2 talking to a P1 in both TX and RX roles from 80 to 376MHz in increments of 10MHz, plus some random oddball freqs here and there (below 80MHz, the driver refused to start; above 376MHz seems maybe the P2 crashed...no sign of life at all post-load), and it both transmitted and received successfully.
I had the same experience with SSD's...switched years ago and have never looked back!
a couple of things I don't understand? how does the SCK_FREQ get calculated? Once I switch from your clock of 160 MHz to my clock of 200MHz.
Next in the obj Wireless transceiver,(NRF) you do not used the passed SCK but insert 5_000_000 instead?
Finally in the DEMO you pass the actual payload last after you have tested all of the retries. I only want to do the retries if there is an actual failure and am not sure how to do it. Since I am eventually running this code without terminals, I will flash an led on the transmitting NRF mpu if there is a transmission error and all of the re-transmits fail. I have replaced all of the serial code comentting out with an if Serial and I set the var to true if I want the serial started and used otherwise I set it to false.
In the SPI engine object, the basic SCK period is calculated by dividing the P1 or P2 clock by the requested SPI clock, to get the period in system clocks (e.g, 160MHz sys clk, 20MHz SPI clock = 8 system ticks period). There's some granularity there, unfortunately, that's worse the higher the SPI clock. This can be improved to a point by increasing the system clock.
The 'SCK_FREQ=5_000_000' in the driver Startx() method just exploits a feature of FlexSpin in that if you don't specify the clock parameter, it uses 5MHz as a default.
As for the retries, I'll have to wait until I get out of work to check for sure, but if i remember correctly, once the chip reaches a certain number of retry attempts, it won't transmit anymore, until the interrupt is cleared.
Okay, I think I'd intended to make sure interrupts were clear before starting, for the demo purposes (that sequence should've been documented), but as a test, I placed everything related to collecting and displaying packet stats to after the payload is transmitted, and it seems to behave ok as well, so I see no obvious problem if it's written that way.
At this point I am truly baffeled and frustrated. I took a week off from work for some much needed R&R and had hoped that I would make some progress with the P2. At this point, I donät even know if any of my NRF modules even work as I have pulled them from other boards to try them on the P2. If I have destroied my boards the project will go on ice for a while until I can get them replaced. If you figure anything out let me know. If you can, try your P2 with a 200MHz clock and let me know what happens.
I hope not...thankfully they're pretty cheap, but still.
As for 200MHz and other clock settings, see my post #12 above - I tested from 80MHz to 376MHz with no issues.
Are you still stuck at the Propeller not being able to talk to the nRF24, or over the air comms issues?
Attached is a dirt-simple program that reads the contents of the RX_ADDR_P0 ($0A) register from the nRF24. Assign your pins at the top of the file and that should be it. If you're able to talk to the chip, it should print the default address, E7E7E7E7E7.
This only uses the serial terminal and SPI objects from my library.
Tried nrf24-conncheck.zip on three boards. Results so far brd1($00000000) brd2 ($FFFF0000),
brd3($ FFFFFFFFFF). So it appears that I have managed to trash 3 boards. Not sure where brd4 is at the moment, but not relevent as I only have 4 and three of them appear to be trashed. Until I accumulate additional funds to get new boards. NRF is out of the picture. I do have some old transceiver boards from another MFR and I recently saw some forum activity giving a link to the P1 OBJ's that drive it, so I may try to make that work for my coms. I appreciate all of the work you have gone through to help me on this project.
Sorry to hear... are you in the US? I'd be willing to donate a few of mine, or new modules from an online seller, if that works for you.
Either way, best of luck!
Yes, I am in US, See pm for addr.and thanks a bunch.
Do me a favor and try your rx check routine with using P6 as VDD and P7 as VSS an tell me what you see.
Oh you're powering the nRF24 board with I/O pins? I didn't realize that...I guess it should be okay though...these shouldn't draw any more than about 15mA. Wouldn't dare try it with one of the boards that has an external amp on it, though (typ., the boards with external antennas).
Nevertheless, I just tried it on my Edge board and it comes up fine:
Meant to ask...this wasn't working for you, with the new modules? Silly question, but I'll ask anyway - have you tried another set of I/O pins? Have you tried powering from the boards power rails rather than I/O pins (at least just as a sanity/diagnostic check).
Just for the heck of it, I measured the current draw of a module in continuous RX mode, and it's almost bang-on what the datasheet says (13.5mA): 13.68mA. This is with a genuine chip, though. I hadn't measured any counterfeit ones before, but I've read that their current draw is quite a bit worse, or at least no real sleep/standby mode to speak of (these _should _draw less than 1uA in sleep, and a few tens of uA in standby).
I realized later, that when in the input mode, the pins are in a high impeadence mode so I can apply 3.3V to the Vdd pin of the NRF board and the P2 will not care. Since the only thing to ever plug into that bank of 8 pins is the NRF no problem is likely to occure.
I am linking to the Kiss thread https://forums.parallax.com/discussion[https://forums.parallax.com/discussion/172225/kiss-eval-board-general-discussion/p1] so that you can see the board that I am using. what I have done is solder female pins onto the inputs from 8 to 15 and plug the NRF board in so that the IRQ pin is in P0 for that bank. If you look at the code I sent earlier you can see how I set up the bank of pins for the method. I have even inserted test code to make the pin numbers are what I expect them to be. when I run NRF24 concheck, I get 020202020202 with the board plugged into bank 1(8-15) and the pins assigned according to the NRF board layout and one of the new boards.. Have you tested concheck with a 200MHz clock? I keep scratching my head and testing theories.
Ooookay, I see why you had the power pins connected that way now. I just threw a quick board together with a female 2x socket on both sides, pass-through like, one for the nRF24 and the other side for the P2 Edge board (pins should be laid out the same way on the KISS), and it still seems to work.
Yes I've tested this all the way from around 80MHz to 300MHz+ - see post 12 above.
Do you have another P2 board you can test with or is the KISS the only one? I bought one as well...will try it tomorrow after work to see if it's any different than the Edge.
One other question that comes to mind: is your copy of p2-spin-standard-library up to date? If it's really old (Oct 2020-ish), the SPI engine had a limitation with the allowed SCK-MOSI-MISO pins layout, because I hadn't yet worked out how to set up the Smart Pins to allow a more flexible I/O pin range relationship between the three. Best to start with newest of both that and the nRF24 driver, as a sanity check.
I have 2 Kiss boards,1 with microsd and 1 without. At this moment, I have only tested the new NRF with a 00 board not an 01. I am not sure about the dates of ny library files so will re+download and specifically replace the Library files with the latest. Today, I have to deal with 2 GFCI brakers that went south yesterday, so will probably not get anything done until Friday.
Just to be thorough, I tested it on the KISS board with success also (tested at 200MHz for the differing crystal freq).
My first inclination is that it's a software issue, so when you have a chance, my above advice still stands - if you've made changes to anything in the p2-s-s-l, back them up somewhere, and from within the p2-s-s-l directory, you should be able to update to the latest with
Hopfully be able to install the new library today, will let you know.
I downloaded new library dated Nov 9. the Spi file Com.spi.spin2 creates the following errors,
line 98 Unknown symbol _cpol
line 102 Unknown symbol _spi_mode
line 187 Unknown symbol nr_words
line 188 Unknown synbol word2spi
I remembered that in previous attempts to compile, I just created VARS with those symbols and then it compiled.
The Update notice at the head of the file is Oct 4, 2021. I wonder if this is where my dificulties lie?
I could not make pull work.
That's embarassing! Because of the way FlexSpin handles dead code removal, if you don't actually use a certain variable anywhere (like if you don't actually call
Mode()in your program), it just optimizes it out/removes it and doesn't produce an error, even if it's not defined. I must not have had any objects call Mode() when I was using the smart-pin engine, so didn't notice those variable definitions were missing.
I have Mode() defined even though it's not currently used because when I started writing it, I'd planned to implement support for SPI modes other than 0 in that particular SPI engine, but wasn't able to figure out how to do it with smart-pins at the time. I decided to shelve the idea for awhile, but wanted to leave the associated methods in there, so that it had API compatibility with my bitbanged engine.
I've just committed a fix for that and defined those variables.
Is it the nrf24-conncheck.spin2 that wasn't building, above? I'd make sure you're not building it in the same directory you have your modified nrf24 sources in, just in case it's picking up that copy of the driver. For the same reason, if you're using the GUI for FlexSpin (FlexProp?), make sure the directory the modified nrf24 driver is in isn't in the list of 'Library directories', else it might pick it up.
Regarding git pull not working - did you download the repository as a zipfile from github? That might be why...I don't think it preserves the .git subdirectory. That's okay though, I wouldn't worry about that right now.
I will delete the vars in question. The Library that has the modified functions will not call because the new name is not in the call list. I will try it and let you know the results.