RF24
RF24 copied to clipboard
ARM64 (JETSON TX2) not working...
Dear all,
I'm trying to make the library work with a JETSON TX2 board but I have some issues. I've modified the configure script and added a soc with the following flags: -->> flags="-march=armv8-a -mtune=cortex-a57" (-mfpu=neon-vfpv4 -mfloat-abi=hard are not recognized by the compiler and SIMD is defaut in ARM64 i think) I'm using the SPIDEV driver.
I'm able to correctly compile and link the library but the module wont configure correctly and obviously do not send/receive data.
Please note: -> I've already tested the modules with two RPi3, using SPIDEV, and they work correctly. -> the spidev driver itself is working correctly (I've jumped the MISO and MOSI pin and made a test) -> the gpios seems also to work well (able to rise up the pin that I'm using via the device file) -> I've used as cepin=388 (gpio388) and cspin=30 (/dev/spidev3.0)
I'm starting to think that the malfunctioning may be related to some issue with the 64 bit architecture of the board.. Have someone ever tried to build on arm64 machine?? Do you have some suggestion?? Am I missing something??
Thanks for the help, Luca
It's possible that there's some kind of a data type size mismatch. However if you connect the module to your board and write a sample script that just reads the module's configuration (you can see which registers contain what from either RF24's source or from the datasheet), does that work? Also how does the library not work for you? If it hangs, please determine where exactly.
Also just mentioning that if it's GCC (on Linux on the board) you can just do -march=native -mtune=native
and you shouldn't need to provide any other flags.
If I try to configure the radio on a RPi3 I obtain this: (correct)
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xccccccccc3 0xcccccccc3c
RX_ADDR_P2-5 = 0x33 0xce 0x3e 0xe3
TX_ADDR = 0x65646f4e32
RX_PW_P0-6 = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA = 0x3e
EN_RXADDR = 0x3f
RF_CH = 0x5a
RF_SETUP = 0x0d
CONFIG = 0x0f
DYNPD/FEATURE = 0x3f 0x04
Data Rate = 2MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_HIGH
Same code in the Jetson I obtain a complete different configuration: (wrong)
STATUS = 0x03 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=1 TX_FULL=1
RX_ADDR_P0-1 = 0x222222e2e0 0x222222220e
RX_ADDR_P2-5 = 0x88 0x23 0x8f 0x70
TX_ADDR = 0x10b0170388
RX_PW_P0-6 = 0x00 0x80 0x00 0x80 0x00 0x80
EN_AA = 0x07
EN_RXADDR = 0x80
RF_CH = 0x05
RF_SETUP = 0xef
CONFIG = 0x80
DYNPD/FEATURE = 0x8f 0x00
Data Rate = 1MBPS <<<---- It should be 2
Model = nRF24L01 <<<--------- Note: It detects a wrong module!
CRC Length = 8 bits <<<-------- I set it to 16
PA Power = PA_MAX <<<--- I set it to HIGH
If I try to receive from jetson it simply doesn't receive nothing... If I try to send it shows me the fail message where it suggest that the wiring may be wrong...
Today I will try to set some registers and read it back using the provided functions and I will let you know!
Thanks for the help!
EDIT: I've tried to operate directly with registers and the communication appear to be broken in some way... If I set a value in the channel register and take it back the value mismatch.
I've exposed the private methods of radio and used the following code:
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <RF24/RF24.h>
#include "nRF24L01.h"
#include "RF24_config.h"
using namespace std;
RF24 radio((uint16_t)481,(uint16_t)30);
int main(int argc, char** argv){
// Setup and configure rf radio
if (!radio.begin()){
return -1;
}
uint8_t ch = radio.read_register(RF_CH);
std::cout << "ch: " << (int) ch << std::endl; //should be 76 (default channel)
radio.write_register(RF_CH, (uint8_t)15);
uint8_t ch2 = radio.read_register(RF_CH);
std::cout << "ch: " << (int) ch2 << std::endl; //should be 15
//just wait...
while(1){
;
}
return 0;
}
The output is the following:
nvidia@nvidia-desktop:~/RF24/examples_linux$ sudo ./registers
ch: 38
ch: 7
Any ideas?? Note: this values seams to be the right shift by one of the original values: ----> 76 >> 1 = 38 ----> 15 >> 1 = 7
May be some issue with a register mask?
Can you use barebones SPI and see if that still has the issue? Knowing if the problem still exists or doesn't would narrow it down to read_register.
I just personally suspect it's some lower-level issue because the one-bit-shift issue hasn't occurred before on other platforms.
I suspect there's some kind of SPI bus misconfiguration, you can read about the different bus configuration possibilities here https://arduino.stackexchange.com/a/13092/11529 but I don't have a Jetson to provide you sample code to set a specific mode.
(Also, post your findings as a new comment, edits don't send notifications out)
Sorry for the late response but I was away from office and I couldn't make tries...
I've some news: ---> By lowering the spi speed to 7 Mhz the channel register appears to be correctly read and written ---> But RX_ADDR_P0-1, for example, is still different from the one on the rpi and communication still not work.
---> I've found out that from the device tree the jetson is configured for spi mode 3:
spi@0 {
compatible = "spidev";
reg = <0x0>;
spi-max-frequency = <17000000>;
spi-cpol = <1>;
spi-cpha = <1>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,cs-setup-clk-count = <0x3>;
nvidia,cs-hold-clk-count = <0x3>;
nvidia,rx-clk-tap-delay = <0x0>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
I don't know if this may be a problem... I think that ioctl should have returned an error if mode 0 was not supported, am I wrong?? I will try to modify directly the device tree configuration to spi mode 0 and flash the new dtb on jetson and see if in this way it works.. I'll keep in touch and thanks for the help!
The mode Arduinos use for SPI is MODE0 (because the SPI bus is configured by the library):
Mode | Clock Polarity (CPOL) | Clock Phase (CPHA) | Output Edge | Data Capture |
---|---|---|---|---|
SPI_MODE0 | 0 | 0 | Falling | Rising |
You are correct that your board is configured differently. I would try setting CPHA and CPOL to 0, but I wouldn't change the speed because it's not really the issue here.
I believe I might have found a relevant bug while working with the Jetson Nano. I was also running into an issue where my pipe addresses were not being set correctly.
In RF24/utility/SPIDEV/spi.cpp, it seems that in SPI::transfernb, cs_change is set =0 by default, which would mean that the chip would not be automatically "hardware deselected" after every transfer. however, after I set the default value of cs_change to 1, I was able to have the pipe addresses set correctly and run the pingpair_dyn.py script successfully.
Not sure about this one.
https://docs.huihoo.com/doxygen/linux/kernel/3.7/structspi__transfer.html
All SPI transfers start with the relevant chipselect active. Normally it stays selected until after the last transfer in a message. Drivers can affect the chipselect signal using cs_change. (i) If the transfer isn't the last one in the message, this flag is used to make the chipselect briefly go inactive in the middle of the message. Toggling chipselect in this way may be needed to terminate a chip command, letting a single spi_message perform all of group of chip transactions together. (ii) When the transfer is the last one in the message, the chip may stay selected until the next transfer. On multi-device SPI busses with nothing blocking messages going to other devices, this is just a performance hint; starting a message to another device deselects this one. But in other cases, this can be used to ensure correctness. Some devices need protocol transactions to be built from a series of spi_message submissions, where the content of one message is determined by the results of previous messages and where the whole transaction ends when the chipselect goes intactive. The code that submits an spi_message (and its spi_transfers) to the lower layers is responsible for managing its memory. Zero-initialize every field you don't set up explicitly, to insulate against future API updates. After you submit a message and its transfers, ignore them until its completion callback. Definition at line 492 of file spi.h.
You may be able to add a #define to SPI.cpp to detect the Jetson and configure cs_change to 1
Just to be clear, I should node that cs_change 1 does not work on RPi. I don't have a scope to see exactly what is going on.
See https://github.com/nRF24/RF24/issues/876#issuecomment-1518269315
We may be able to close this issue in couple weeks (when Ububtu18.04 hits EoL).
after I set the default value of cs_change to 1, I was able to have the pipe addresses set correctly
This may be specific to the Jetpack SDK since it includes the Linux kernel (which may be customized though not explicitly mentioned in the docs). Remember that the payload data is only queued in the radio's TX FIFO when the CSN pin goes inactive (for any SPI transaction that involves a payload).
Reminder to passers-by, the newer CMake install instructions are required for a 64-bit OS