This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/TRF7970A: RSSI Register Reading 0xFF

Part Number: TRF7970A

Tool/software: Linux

Hey There,

I'm working on developing an RFID driver for an embedded product. Right now I'm using the TRF7960TB EVM board with a TRF7970A chip installed. It is communicating via SPI with a MittySOM-5CSX SoC. There is one other SPI device on the same bus. The Vin line is a 5V signal from the power supply, EN is attached to a GPIO on the processor, and EN2 is tied directly to ground. The EN signal is getting set high when the drivers perform the power on function.

I have compiled the TI trf7970a drivers for my device as well as the neard stack which I'm using to interface with the low level drivers. I'm trying to get a "hello world" working with the chip as an Initiator. I've built the TI drivers with debug enabled and am using the neard example code to get running (the test-adapter python script inside the 'test' folder of the neard source).

The device appears to be powering up fine, but when it goes through it's initial anti-collision process (command 0x19) the RSSI status register returns as 0xFF. This doesn't make much sense to me as B7 of the RSSI register is unused, and the default value for it is 0x40. Not only is it unlikely that those 3 LSB should be high, but why is the MSB also being set high? I've added the debug log below. Has anybody experienced this before? Any suggestion for which direction I should be heading next?

Best,

Ben

Relevant lines from /var/log/debug:

May 23 13:45:45 mitysom-5csx-h6-4ya_4 kernel: [    4.226456] trf7970a spi32766.0: IRQ - state: 0, status: 0x0
May 23 13:45:45 mitysom-5csx-h6-4ya_4 kernel: [    4.236283] trf7970a spi32766.0: Powering up - state: 0
May 23 13:47:15 mitysom-5csx-h6-4ya_4 kernel: [   95.922212] trf7970a spi32766.0: Switching RF - state: 1, on: 1
May 23 13:47:15 mitysom-5csx-h6-4ya_4 kernel: [   95.922233] trf7970a spi32766.0: Switching rf on
May 23 13:47:15 mitysom-5csx-h6-4ya_4 kernel: [   95.925726] trf7970a spi32766.0: Initializing device - state: 1
May 23 13:47:15 mitysom-5csx-h6-4ya_4 kernel: [   95.925738] trf7970a spi32766.0: cmd: 0x83
May 23 13:47:15 mitysom-5csx-h6-4ya_4 kernel: [   95.925844] trf7970a spi32766.0: cmd: 0x80
May 23 13:47:15 mitysom-5csx-h6-4ya_4 kernel: [   95.927948] trf7970a spi32766.0: write(0x9): 0x0
May 23 13:47:16 mitysom-5csx-h6-4ya_4 kernel: [   95.941173] trf7970a spi32766.0: write(0x14): 0xf
May 23 13:47:16 mitysom-5csx-h6-4ya_4 kernel: [   95.953323] trf7970a spi32766.0: write(0x10): 0x0
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  101.986406] trf7970a spi32766.0: Configure hw - type: 0, param: 0
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  101.991890] trf7970a spi32766.0: rf technology: 0
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  101.991911] trf7970a spi32766.0: write(0x18): 0x0
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.013012] trf7970a spi32766.0: Configure hw - type: 1, param: 0
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.017635] trf7970a spi32766.0: framing: 0
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.028861] trf7970a spi32766.0: write(0x0): 0x3
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.045335] trf7970a spi32766.0: cmd: 0x99
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.050421] trf7970a spi32766.0: read(0x4f): 0xff
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.055294] trf7970a spi32766.0: write(0x0): 0x1
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.093169] trf7970a spi32766.0: Switching RF - state: 2, on: 0
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.093184] trf7970a spi32766.0: Switching rf off
May 23 13:47:22 mitysom-5csx-h6-4ya_4 kernel: [  102.093197] trf7970a spi32766.0: write(0x0): 0x1
  • Hello Ben,

    I agree that is very unusual, I've never seen such an occurrence before. Reading that register is actually one of the tests to check if the device is brought up correctly as the Crystal Oscillator bit is always used. You are correct that B7 is not supposed to be high, it should never show a high signal.

    I've never seen this before so I can't comment what exactly may be going on wrong, but my best guess would be that something on the soldering of the TRF7970A is incorrect. The TRF7960TB has all the required external components including the pulldown needed for the EN line, so from a hardware perspective the board itself is fine. Beyond something like not being soldered right, I can't think of any reason a 0xFF would be returned. When SPI doesn't work the result has been a 0x00...

    Also I wanted to mention: "There is one other SPI device on the same bus"
    - The TRF7970A SPI bus does not go high impedance when SS is raised high, only if the EN is pulled low to disable the device. Therefore if you are not going to pull EN low when operating the other SPI device, you will need to use tri-state buffers on the SPI lines. This is explained in Section 7.1 of this document: www.ti.com/.../sloa159a.pdf
  • Hi Ralph,

    Thanks for the quick response. I have multiple of the RFID modules, so I tried putting a new one on the board but still had the same issue - it doesn't seem like it's a soldering issue. My next step is to put an SPI debugger onto the board to make sure that the Linux SPI drivers that are ultimately controlling the read values are working correctly.

    I saw the SPI device note, but strangely enough the MISO line appears to be in a high impedance state, with the MISO line settling within about 1ms of SS being raised high. Not sure what's going on there or if it's related. I'm also curious if there is any chance that the startup sequence has anything to do with this?

    My board only has the EN line controllable. When our team designed the motherboard we were unaware of the startup timing constraints, so later we brought out the EN line to an unused GPIO pin as a workaround. This means that instead of having the suggested timings in the datasheet, Vin is powered at boot, and then when the kernel loads the trf drivers, the EN line gets asserted. This time ends up being significant longer than the suggested time between Vin and EN. Would this cause any issues with the read?

    Best,
    Ben
  • Hello Ben,

    I think the SPI debugger is the correct approach.

    I am not sure about the expected behavior of the SPI lines when SS is raised high beyond the documentation honestly. That was all documented before my time and it hasn't come up before.

    Regarding the EN line - the timing is meant to be a minimum. There's no issue with taking a lot longer at all. EN is used to toggle the device on and off, so many applications will raise it far after the VIN signal is applied. What's important is to the follow the timing between SS high and EN high. If you aren't sure if that's being done, you can try applying the en2-rf-quirk. That should handle all of the timings if I remember what it does correctly. It shouldn't matter that EN2 isn't connected to the GPIO to use that.
  • Hi Ralph,

    I've done a bit more debugging since we last talked and am unfortunately still stuck, but I have found out some things while testing and I'm hoping the added information might help. I attached an SPI analyzer and all it did was confirm that the data I was being shown in the debug log (/var/log/debug) was in fact what was being put on the SPI lines. I also attached a scope to the MISO line and confirmed visually that I was getting an 0xFF when I attempted to read this register.

    So far I had not interfaced directly with the driver (I've only been using neard in python so far), but I created a user space C application in an attempt to try some things out. I let the TI driver do the power-up sequence (asserting EN and SS), and then sent a software init command (0x83) and an idle command (0x80). I then ran the following commands:

    trf7970a_write(trf, TRF7970A_RAM1, 0x55);
    
    usleep_range(50, 60);
    
    trf7970a_read(trf, TRF7970A_RAM1, &val);

    The intent of this was to write any value to ram and then immediately read it. Unfortunately it returned 0xFF. As far as I can tell all I am getting from the trf device is either an 0x00 or 0xFF, which definitely sounds like an SPI problems.

    Other things I've looked at is the IO_X lines, confirming IO1/IO2 were both high at power on and IO0 was grounded. I've confirmed the clock speed for our SPI line (1MHz), and that the device tree is configured for the TRF for a maximum frequency of 1MHz.

    I'm away from my hardware today, but I'll be sure to get some scope traces / analyzer outputs when I can. Any chance you have any insight on the problem with the extra info?

    Best,

    Ben

  • Hello Ben,

    The minimum specified Data CLK speed for the SPI lines on the TRF7970A is 2MHz. Please increase the SPI clock frequency to that and test this again.
  • Hi Ralph,

    I set my SPI bus to use a 2MHz clock and I got the same results. I also confirmed on the scope that I was in fact generating a 2MHz clock. The output of my /var/log/debug file is as follows, this includes an initial power up / powerdown when the device is loaded at bootup, and then 2 minutes later I run my python script that goes through the startup sequence up until the collision detection, where I get the same 0xFF read.

    Jun  1 10:06:48 mitysom-5csx-h6-4ya_4 kernel: [    3.025390] trf7970a spi32766.0: IRQ - state: 0, status: 0xff
    Jun  1 10:06:48 mitysom-5csx-h6-4ya_4 kernel: [    3.025675] trf7970a spi32766.0: Powering up - state: 0
    Jun  1 10:07:16 mitysom-5csx-h6-4ya_4 kernel: [   33.120374] trf7970a spi32766.0: Runtime suspend
    Jun  1 10:07:16 mitysom-5csx-h6-4ya_4 kernel: [   33.120396] trf7970a spi32766.0: Powering down - state: 1
    Jun  1 10:07:16 mitysom-5csx-h6-4ya_4 kernel: [   33.121256] trf7970a spi32766.0: IRQ - state: 0, status: 0xff
    Jun  1 10:07:16 mitysom-5csx-h6-4ya_4 kernel: [   33.128199] trf7970a spi32766.0: IRQ - state: 0, status: 0xff
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.435981] trf7970a spi32766.0: Switching RF - state: 0, on: 1
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.436001] trf7970a spi32766.0: Switching rf on
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.436018] trf7970a spi32766.0: Runtime resume
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.436030] trf7970a spi32766.0: Powering up - state: 0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.463109] trf7970a spi32766.0: Initializing device - state: 1
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.463127] trf7970a spi32766.0: cmd: 0x83
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.463218] trf7970a spi32766.0: cmd: 0x80
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.465303] trf7970a spi32766.0: write(0x9): 0x0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.465367] trf7970a spi32766.0: write(0x14): 0xf
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.465441] trf7970a spi32766.0: write(0x10): 0x0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469279] trf7970a spi32766.0: Configure hw - type: 0, param: 0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469298] trf7970a spi32766.0: rf technology: 0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469312] trf7970a spi32766.0: write(0x18): 0x0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469410] trf7970a spi32766.0: Configure hw - type: 1, param: 0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469425] trf7970a spi32766.0: framing: 0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469437] trf7970a spi32766.0: write(0x0): 0x3
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469543] trf7970a spi32766.0: cmd: 0x99
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469930] trf7970a spi32766.0: read(0x4f): 0xff
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.469946] trf7970a spi32766.0: write(0x0): 0x1
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.477649] trf7970a spi32766.0: Switching RF - state: 2, on: 0
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.477666] trf7970a spi32766.0: Switching rf off
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.477678] trf7970a spi32766.0: write(0x0): 0x1
    Jun  1 10:09:17 mitysom-5csx-h6-4ya_4 kernel: [  153.478305] trf7970a spi32766.0: Abort process initiated
    Jun  1 10:09:47 mitysom-5csx-h6-4ya_4 kernel: [  184.080372] trf7970a spi32766.0: Runtime suspend
    Jun  1 10:09:47 mitysom-5csx-h6-4ya_4 kernel: [  184.080394] trf7970a spi32766.0: Powering down - state: 1

    I've also attached the output from my SPI analyzer of this same run. This is showing that what the trf drivers is reporting in the debug log is the same as what is on the lines. I can get some scope shots of the SPI communication and the startup sequence in a bit, but I'm wondering if you have any other ideas of what could be wrong.

    Best,

    Ben

    3660.spi_log.zip

  • Hello Ben,

    From what I could tell from your log, nothing seemed off or out of place software wise.

    I would recommend to get one of the TI evaluation setups and compare the SPI timings, waveforms, and data between your setup and our EVM setup:

    - Hardware: https://store.ti.com/nfclink-bndl.aspx

    – Firmware: http://www.ti.com/lit/zip/sloa227

    – For details, see NFC/HF RFID Reader/Writer Using the TRF7970A.

    Also to 100% rule out hardware, you can purchase the TRF7970ATB EVM as well instead of soldering chips onto the TRF7960TB. I know you mentioned you tried multiple boards, but that doesn't 100% rule it out from our point of view. Since we do offer the correct EVM for your system, I think you should try that as well.

  • Hey Ralph,

    I am using the TRF7970ATB EVM, I was mistaken before when I said it was the 7960. My next debugging step is going to be trying out one of the eval kits.

    In the meantime I have a question: I see that the NFC drivers send an IRQ read message (0x6C) to the TRF (timestamp 3.025390 in my above log) before the powerup sequence. Because this happens before the powerup sequence, the first message occurs before EN is asserted. Is this the intended behavior of the TRF drivers? This message is the very first thing the drivers send when the kernel module gets loaded.

    I've also attached some scope traces that I've collected. Let me know if you see anything amiss.

    Best,

    Ben

  • Hi Ben,

    It's weird the driver would do that before turning EN high but I also don't see that being an issue ultimately related to this since the device would just ignore the command then. Actually it probably wouldn't even receive it since when EN is low, the SPI pins should be High-Z. I wouldn't say it's intended, but the neard stack for using the TRF7970A with Linux is not developed in house so it's not something we can easily address.

    Gotcha on the hardware - that checks out at least, thanks for clarifying that.
  • Hey Ralph,

    Just for clarification, this behavior wouldn't be controlled by the neard stack but instead by the TRF drivers or the Linux NFC-subsystem drivers. The IRQ read comes immediately after the kernel module is loaded, while the neard portion of the stack is something that I manually load in user space (in a similar fashion to that found in www.ti.com/.../sloa210.pdf, where I call the neard executable from the command line).

    -Ben
  • Hi Ben,

    Gotcha, well, the entire Linux example from sloa210 is done outside of TI so I have limited knowledge about it as a whole as I just clearly illustrated with my attempt answer... I don't really know why the IRQ Status read is done randomly like that because none of our MCU based drivers would do that before the startup sequence. But anyways, I don't think that's a root cause for this situation - and the startup sequence itself, which I can speak to with expertise, looks to be just fine based on the capture provided as far as commands issued goes, including the delay after the Soft Init/Reset sequence.
  • Hi Ralph,

    Is there anyone at TI who would be more familiar with these drivers that could possibly look at my issue? In particular the trf drivers and how they interact with the NFC subsystem, as I haven't gotten past this part. I'm going to start looking at the signals from our eval board, but the extra time I allocated for developing these drivers is running out.

    Best,
    Ben
  • Hi Ben.

    Chances are that you are not actually reading the trf7970a's registers at all and are getting 0xff which is what is returned when there is no device at the other end. It just so happens that the RSSI register is the first one read by the driver so you notice it first. I expect that all register reads return 0xff.

    There could be several causes but the first one that comes to mind is that your device tree (DT) is incorrect. Please check that you have the pinmux configured correctly and that you have the proper spi controller specified, etc. You can check the pinmux register values by cat'ing /sys/kernel/debug/pinctrl/44e10800.pinmux/pins. Also verify that you are using the DT that you think you are by using (e.g., 'dtc -I fs -O dts /sys/firmware/devicetree/base' or manually looking around /sys/firmware/devicetree/base).

    In order to help you more, you need to provide more information. Where did you get your kernel and which version are you using (e.g., TI SDK, community)? Where did you get your root filesystem from (TI SDK or debian or ...)? What does your DTS file look like?

    Note that sloa120 is pretty dated now if you are using a more recent TI SDK. There is a new one in the works that should be out soon.
  • Hi Mark,

    Sorry for the late response, I've been unable to work on this project for the last week. I'm working with the mitysom-5csx SOM, which has a Cyclone V FPGA on it and 2 Cortex-A9 ARM processors. On the software end I'm building everything using the Altera 14.1 toolkit, which uses arm-linux-gnueabihf-* build tools.

    I agree with the idea that SPI isn't working, but I'm not sure where it would fail. Our pre-loader configures the pinmux and all of the SPI lines with the exception of MISO are behaving as expected, with the MOSI/clk/ss lines all acting correctly when the processor writes to the SPI bus. Since the pre-loader handles the pinmux I don't believe I need the pinmux property for the TRF device tree entry. It looks like you're speaking from experience with a beaglebone, which is a slightly different setup.

    I'm using a real time kernel 4.1.22-ltsi-rt. This was provided by Critical Link along with a rootfs for use with the Mitsom, but ultimately comes from the Yocto project. I compiled the kernel from scratch adding some additional build options for my board, such as NFC and RTC. All of the libraries that were needed by NEARD that were missing from the rootfs I compiled from scratch and put in the /lib folder.

    I've attached my dts, but the TRF entry is as follows:

    			spidev@0 {
    				compatible = "ti,trf7970a";
    				reg = <0>;
    				spi-max-frequency = <2000000>;
    				interrupt-parent = <&pio_2>;
    				interrupts = <0 42 4>;
    				ti,enable-gpios = <&pio_0 0 1>,
    						<&pio_0 1 1>;
    				vin-supply = <&supply5v>;
    				vin-voltage-override = <5000000>;
    				autosuspend-delay = <30000>;
    				irq-status-read-quirk;
    				en2-rf-quirk;
    				enable-dma = <1>;
    				status = "okay";
    			};

    Let me know if any of this raises any red flags or if you need any more info.

    Best,

    Ben

    socfpga_mitysom5csx_custom.zip

  • Hi again, Ben.

    Thanks for the info and your DTS file.

    First a few things about your DTS file:
    - Don't name the trf7970a's entry 'spidev', there is nothing spidev related in that block of properties (nor is there for the one following it). Name it for what it is: 'trf7970a'.
    - The trf7970a driver does not use DMA so you should remove the 'enable-dma' property.
    - The vin-voltage-override property is unnecessary (and possibly wrong). If you have your supplies/regulators configured/connected correctly, you don't need that property. A patch to remove support for that property is working its way to the mainline kernel.

    Otherwise, it looks okay *I think* but I didn't follow the gpios and I'm assuming that your firmware really does set up the pinmux correctly. Speaking of which, did you confirm that the pinmux is configured correctly using the suggestions I gave you before? Don't assume that firmware does it right and don't assume that some other piece of the composite DTS file doesn't do something that is messing you up. For example, for the Beaglebone Black with the trf7970a on spi1, I have to disable mmc2 and mcasp0 (disable means setting the status for that device to "disabled").

    Have you checked that there is appropriate power to the various V(foo) pins? Have you confirmed that EN and EN2 are high and always low, respectively? Were there any messages in the boot log indicating some sort of issue?

    Lastly, what do you mean by, "all of the SPI lines with the exception of MISO are behaving as expected"? Is there something wrong with MISO or are you referring to the fact that the driver only sees 0xFF's?
  • Hi there all,

    I just realized I never updated this with the fix I found. Better late then never I guess.

    It appears that the implementation of the SPI drivers in my kernel didn't behave in the necessary way for the trf7970a (or maybe it was my spi controller, I'm not sure).

    Whenever a read is done the SPI master must first assert the SS line low, write the address, read the value on the MISO line, and then release the SS line. It turns out that my system was releasing the SS line after the address write and then pulling it back low for the read. The TRF didn't know how to handle this and wouldn't put anything on the MISO line, resulting in everything being read as either an 0x00 or a 0xFF - depending on the state of the MISO line at the time of the "read".

    To fix this I had to modify the kernel drivers. I reconfigured the SS line as a GPIO on my FPGA and am manually controlling it in the drivers. Before every line that calls 'spi_write_then_read', 'spi_write', or 'spi_sync' I set the SS line low, then set the SS line high immediately after the call. This made it so the SS line is held low for the entirety of every SPI transaction, which fixed things for me.

    Best,
    Ben