1

I'm currently trying to make a NRF24L01 module work by using Java. I found this library that makes use of the JNI, but I can't get it to work.

When I try to run the provided example code the Raspberry Pi just hangs and the CPU rises to 100% after (or rather while) running rf24.begin().

I digged a little bit into the code and found out that the reason it hangs is due to an endless while loop inside the bcm2835_spi_transfernb() function of this file.

The function is the following:

void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
{
    volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
    volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
    uint32_t TXCnt=0;
    uint32_t RXCnt=0;

    // This is Polled transfer as per section 10.6.1
    // BUG ALERT: what happens if we get interupted in this section, and someone else
    // accesses a different peripheral?

    // Clear TX and RX fifos
    bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);

    // Set TA = 1
    bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);

    // Use the FIFO's to reduce the interbyte times
    while((TXCnt < len)||(RXCnt < len))
    {
        // TX fifo not full, so add some more bytes
        while( (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD )  && (TXCnt < len )  && !(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXR) )
        {
           bcm2835_peri_write_nb(fifo, tbuf[TXCnt]);
           TXCnt++;

        }   
        //Rx fifo not empty, so get the next received bytes     
        while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len )){        
           rbuf[RXCnt] = bcm2835_peri_read_nb(fifo);
           RXCnt++;    
        }
    }
    while(! (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_DONE) ){}
    if(TXCnt == len){ bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);}
}

The problem is that the two while loops inside the outer while loop are never entered and therefore the exit-condition cannot occur turning this into an endless while loop.

Unfortunately I have no idea why that happens. Is it possible that this is due to a SPI related problem, like me forgetting to setup something? I did enable the SPI interface and validated it multiple times and also tested it. It seems to be working correctly. I also checked my wiring multiple times and I'm confident that its correct.

I would appreciate a little input, since I am really lost regarding this right now.

  • Well, there are a couple of reasons that the SPI transfer goes into an infinite loop. Usually first thing first is to use a SPI loopback test to make sure the SPI software and hardware are properly setup and the wiring is good. In case you are not familiar with SPI loopback in general and nRFL2401+ specifically, you might like to skim the following chat record: chat.stackexchange.com/rooms/107068/…. – tlfong01 Apr 24 at 2:40
  • Your references are out of date. You need to update the tools: (1) anvo/rf24-bcm-java Java wrapper for the nRF24L01 library - 2014 github.com/anvo/rf24-bcm-java (2) TMRh20 RF24/RPi/RF24/bcm2835.c - Mike McCauley 2013 github.com/stanleyseow/RF24/blob/… (3) Arduino and Raspberry Pi driver/libraries for nRF24L01 github.com/stanleyseow/RF24 - 2014 github.com/stanleyseow/RF24 (4) Optimized high speed nRF24L01+ driver class documentaion V1.3.4 - TMRh20 2020 tmrh20.github.io/RF24. – tlfong01 Apr 24 at 2:42
  • 1
    I actually performed a SPI loopback test and it was successful. Could you please elaborate though what you mean with "updating" my tools? I saw that the submodule the Java wrapper uses is very old, since someone else is now maintaining the library. Do you mean I have to use that newer code? If so, how am I supposed to do it? I think "simply" changing the submodule will mess with the rest of the code. – Gereon99 Apr 24 at 10:32
  • Just a couple of quick comments: (1) SPI loopback: I usually first do SPI loopback. As you might know, SPI loopback only makes sure MOSI and MISO is working more or less properly, but CE0 or CE1 is not tested. To make sure all three signals are tested, I usually do the ping test. For nRF24L01+, I do the following: (2) Read the nRF24L01+'s config register at address 0x00, to see if the POR value is 0x04. (3) I sometimes also do the read-after-write test: write random values 0x00, 0xff, 0x55, 0xas, 0x5a, 0xa5 etc to make sure I can read after write OK. – tlfong01 Apr 24 at 12:31
  • 1
    Thank you for your effort. I might try reading e.g. the config register with Pi4J as suggested by you. Thats a good idea. – Gereon99 Apr 24 at 14:16
1

A few days have passed and I decided to kinda "rewrite" this lib. (I copied a lot)

Its not as extensive, but it works well for me. If anyone is interested to try it out: Here.

I didn't add tons of documentation though, so be warned.

| improve this answer | |
1

Answer

(1) After googling a bit, I have decided to start with Rpi BlueJ Java IDE, and the first Java programs will be on:

(a) GPIO LED/Button programming,

(b) SPI programming.

(2) Next step is to study existing nRF24L01+ Python/Java libraries and see how to expand the libraries with more features.

(3) I also found that Pi4J libraries include SPI. So I guess I should jump start to Pi4J and see if I can just use it to read nRF24L01's config register, which is what I wanted to do in the very beginning.

(4) I think I can first try to use Pi4J to read the nRF2410+'s config register at address 0x00, hopefully getting the POR (Power On Reset) value of 0x00.

If no luck, I will fall back to do SPI loopback test, to check if I need to adjust the SPI speed to a lower value, say from 5MHz to 1MHz.

If still no luck I will give up SPI for now and try to do the easier Ri4J GPIO, testing GPIO read/write of the nRF24L01+'s Reset pin and Interrupt pin.

rf module 1

rf module 2

(5) Now I am following the BlueJ and Pi4J tutorials (Refs 8 ~ 14) to do my newbie Java GPIO and SPI programming exercises.


ERRATA

I found the tutorials referred above are much out of date. So I googled harder and found a couple of very up to date tutorials, and other too good to be true things including the following:

(1) BlueJ already includes Pi4J, therefore no need to install.

(2) Rpi buster already includes JDK, therefore no need to install.

(3) BlueJ also includes GPIO classes for Rpi.

(4) BlueJ already includes tutorials on LED, button, servos, analogue sensors, including MCP3008.

In other words, my tentative plans in Sections 1 to 4 above are all rubbish!

bluej rpi


(6) If BlueJ already includes Pi4J which in turn includes SPI, I think they are very mature or stable and should have very little teething problem, so is not much need to do any feasibility study. In other words, we can just do a incremental/continuous TTD (Test Driven Development) starting from the very bottom, GPIO control of the NRF24 Reset and Interrupt pins, using BlueJ's LED and Button tutorials as a reference. Here is a top down schematic of the overall test plan.

nrf24 schematic

(7) I found a more updated 2016 tutorial also by Kölling, Educational Programming on the Raspberry Pi - M Kölling, Electronics, 5 (3) 2016

I skimmed this tutorial and found it very useful to know the basic idea of creating the tools GreenFoot and BlueJ.

(8) Now I am reading the Pi4J SPI Class. The documentation looks good:

pi4j spi class

(9) Java JNI learning notes

JNI


/ to continue, ...


References

(1) Installing Java on the Raspberry Pi (OK for Rpi4 buster) - Emmet, PiMyLifeUp 2019dec12

(2) Efficient Java Development for the Raspberry Pi - GregF10 2018

(3) How to Install Java on Raspberry Pi - 2020feb24

(4) BlueJ - Wikipedia

(5) GreenFoot

(6) The BlueJ system and its pedagogy - M Kölling etal 2003dec

(7) BlueJ on the Raspberry Pi - BlueJ.org

(8) BlueJ LED Tutorial - BlueJ.org

(9) Raspberry Pi - Programming Pi-Face with Java & Pi4J (SPI)

(10) Java SPI using com.pi4j.wiringpi Class

(11) The BlueJ Tutorial Version 2.0.1 for BlueJ Version 2.0.x - Michael Kölling

(12) The BlueJ Environment Reference Manual Version 2.0 for BlueJ Version 2.0

(13) Pi4J Java I/O library for the Rpi (Rpi3B+ OK, but no guarntee for Rpi4B)

(14) Getting Started with BlueJ, Creating and Running programs in BlueJ - UT CS

(15) Educational Programming on the Raspberry Pi - M Kölling, Electronics, 5 (3) 2016

(16) BlueJ on the Raspberry Pi

(17) Pi4J Overview

(18) Java Programming Tutorial Java Native Interface (JNI) - www3.ntu.edu.sg


Appendices

Appendix A - Install OpenJdk v11.0.6

(1) Installing Java on the Raspberry Pi (OK for Rpi4 buster) - Emmet, PiMyLifeUp 2019dec12

openjdk install


Appendix B - Using MicroSoft Visual Studio Code

magpi java 1

magpi java 2

/ to continue, ...


| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.