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.

XRDY IRQ while no data to send problem

Other Parts Discussed in Thread: OMAP3530, PCA9555, BQ27541-V200

I2C problem description:

Platform:
Torpedo SOM with OMAP3530 Rev 3.1
Linux 2.6.28.rc8

I2C Configuration:
I2C slave devices attached to I2C bus#2
I2C device 1-> pca9555 16-bit I2C-bus I/O port with interrupt
I2C device 2-> bq27541-V200 Single Cell Li-Ion Battery Fuel Gauge for Battery Pack Integration
I2C bus speed is set to 400KHz
I2C bus pull ups changed from 10Kohms to 2.2Kohms.

General Information:
We have a multi threaded Linux application that runs on the OMAP. Several threads within the Linux
application communicate with the I2C slave devices. Access to the I2C bus #2 resource is controlled
using a pthread mutex. The application also communicates over USB to a PC based application.

Under what circumstances have we observed the error:
--A majority of the observed errors occur when the OMAP Linux application is communicating with the
PC application over USB.
--A significant portion of the instances of this error occur at about 1 hour of application operation.
--However we have observed the error within seconds of starting the PC application.
--We have observed the Linux application run overnight in cooperation with the PC application without
error. The PC application performs periodic communication with the Linux application.
--Our method to reproduce the error entails running the Linux and PC applications and using the PC
application to command the Linux OMAP application to perform a task that intensively uses the SPI bus.

What do we see when the error occurs:
A message from the kernel prints on the console as follows: "i2c_omap i2c_omap.2: XRDY IRQ while no data to send".
The Linux kernel prints this message under the following conditions (see drivers/i2c/busses/i2c-omap.c)
1. we receive an XRDY interrupt (see I2C_STAT register, TRM pg 2785)
2. the kernel buffer to transmit is empty.
Once we start receiving this message we get them at a frequency of > 1MHz indefinitely. Also the kernel still
reports some rndis messages

Following are all the I2C instance 2 registers listed on page 2781 in table 18-25 of the TRM at the time of
the error.

i2c_omap i2c_omap.2: XRDY IRQ while no data to send [ISR exit:)]
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_IE_REG     (0xd8072004) 0x601f
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_STAT_REG   (0xd8072008) 0x0010
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_WE_REG     (0xd807200c) 0x636f
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_SYSS_REG   (0xd8072010) 0x0001
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_BUF_REG    (0xd8072014) 0x0303
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_CNT_REG    (0xd8072018) 0x002b
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_DATA_REG   (0xd807201c) 0x008f
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_SYSC_REG   (0xd8072020) 0x0215
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_CON_REG    (0xd8072024) 0x8602
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_OA_REG     (0xd8072028) 0x0000
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_SA_REG     (0xd807202c) 0x0020
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_PSC_REG    (0xd8072030) 0x0004
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_SCLL_REG   (0xd8072034) 0x0012
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_SCLH_REG   (0xd8072038) 0x0012
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_SYSTEST_REG(0xd807203c) 0x0000
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_BUFSTAT_REG(0xd8072040) 0x0024
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_OA1_REG    (0xd8072044) 0x0000
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_OA2_REG    (0xd8072048) 0x0000
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_OA3_REG    (0xd807204c) 0x0000
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_IE_ACTOA   (0xd8072050) 0x0000
i2c_omap i2c_omap.2: I2C Reg OMAP_I2C_IE_SBLOCK  (0xd8072054) 0x0000
i2c_omap i2c_omap.2: XRDY IRQ while no data to send [ISR exit:)]

What fix attempts have been tried:
1. We reviewed the OMAP 3530 errata (sprz278e.pdf) relating to I2C and found 2 errata whose descriptions seemed
   close to what we were seeing.
   -1. Advisory 3.1.1.15 I2C: RDR Flag may be Incorrectly Set (see sprz278e.pdf pg. 20)
    -2. Advisory 3.1.1.153 I2C: Data Lost on Transmission from Memory to I2C Interface (see sprz278e.pdf pg. 59)
   We looked at our current kernel's I2C ISR implementation and compared it against 2.6.36.rc1 I2C ISR. We noticed that
   new code has been added that directly relates to the 2 errata mentioned above. We put the errata related code into
   our kernel version 2.6.28.rc8. Specifically we put the code into drivers/i2c/busses/i2c-omap.c.
   Result == problem still present.

2. We put all changes between 2.6.28.rc8 I2C ISR and 2.6.36.rc1 I2C ISR into our I2C ISR in drivers/i2c/busses/i2c-omap.c.
    Linux 2.6.28.rc8 + (omap_i2c_isr from 2.6.36.rc1)
   Result == problem still present.

3. We were using 10Kohm pull ups on the I2C lines and we changed them to 2.2Kohm pull ups
   Result == problem still present.

4. We changed the I2C bus speed from 400KHz to 50KHz.
   Result == problem still present.

Questions follow:

1. What to look at / try next?

2. Has anyone else observed a similar problem?

  • Hi!

    Thanks for the detailed description of the issue.  The register dumps are a decent start, but I think in order to track this further I think we need to know some more about the chain of events leading to this problem.  Here's what I recommend:

    • Find the code that prints out the message, "XRDY IRQ while no data to send"
    • In that same error condition, just before the printf, toggle a GPIO pin.
    • The GPIO pin you toggle should be connected along with SCL and SDA to a logic analyzer (hopefully one with I2C parsing).
    • You should setup the logic analyzer for "single shot" run such that it grabs all the data leading up to this error condition.

    I did some analysis of your registers to see if I could find anything that jumped out.  Here's my take:

    • I2C_CON:
      • MST=1, TRX=1 ---> "Master transmit" mode
      • STT=0, STP=1 --->  After initiating a "start" the STT bit auto-clears, but STP does not clear until the counter gets to zero when the stop condition gets sent.  So looking at STT and STP it looks sort of like you're in the middle of a transfer.
    • I2C_STAT:
      • BB=0.  Normally once a start condition has been issued you would see BB=1.  So this seems inconsistent with the I2C_CON register settings in that it does NOT appear like we're in the midst of a transfer.

    Please post a screen capture from your logic analyzer once you're able to catch the failure.  It might also be interesting to know if the failure always happens after a write to the same slave address if you run it many times.

    Best regards,

    Brad

     

  • We were able to narrow down the start of bad I2C transactions to a line of code that forked a new process. It turns out that our application forks and creates new processes. When we fork, the OS creates new processes which contain duplicate file descriptors. One of the file descriptors that is duplicated is the file descriptor we use to communicate with the I2c bus. Apparently one of the forked processes incorrectly writes to the I2c bus generating the bad I2C transactions we observed. So we ensured that our I2C file descriptor was closed in the forked processes (by using the O_CLOEXEC when we opened the initial file descriptor) and the problem disappeared.