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.

TMS355DM355 as I2C Slave/ Missing Interrrupt

Other Parts Discussed in Thread: TMS320DM355

We are using TMS320DM355 in one of our Products. It is acting as slave-device on the I2C Bus. For this I have made some changes to the I2C Driver in 2.6.18 Kernel. This seemed to work fine for over two years now. Recently we have created a Software update for the device. Now we have the problem that the I2C Device sometimes got stuck, but let me explain in detail what we have done:

 

- First of all, after system start, UBL (unmodified from DVSDK 2.10) gets loaded from the NAND.

 

- Then UBL loads UBOOT. We have modified UBOOT. UBOOT sets GIO 014 and GIO 015 as Inputs, and PIN R13 and R14 from I2C_SDA/SCL to GIO 014 and GIO 015 within PINMUX3 Register. Why we do so? We have experienced that DM355 blocks I2C on Startup. To avoid this, we set the PINs as Inputs, so that I2C Bus is not blocked.

 

- Now the Kernel gets loaded (including the I2C Driver). Kernel is not changing PINMUX3!

 

- When the user-space gets loaded, we load a self-written kernel module which changes PINMUX3 (PIN R13 and R14 got connected to I2C_SDA/SCL). Now DM355 answers with acknowledge when it detects his Slave-address.

 

We Poll DM355 by the Address set in the I2C-kernel-driver and most times the transfer works fine, but sometimes it doesnt.

 

So whats happening on the I2C-bus?

 

When everything works fine:

 

Start DM355 7Bit Adress ACK 8Bit Data ACK 8Bit Data ACK Stop

 

When its not working:

 

Start DM355 7Bit Adress ACK 8Bit Data ACK 8Bit Data ACK SCL and SDA kept low by DM355

 

 

I checked Registers of I2C module while the AAS Interrupt occurs:

 

ICIMR:              0x7F

ICMDR:            0x20

ICSTR:             0x1E18

ICEMDR:          0x0

 

Same Register Values when failure happens.

 

But now what is curious:

When the system works fine, I get the AAS-Interrupt and next the ICRDY-Interrupt.

 

When DM355 blocks the I2C-Bus, there is no ICRDY-Interrrupt after the AAS-Interrupt (but ICIMR is set to 0x7F).

 

So what is happening here? Without changing anything on the System, the Interrrupt sometimes just not occur!

Are there any Application-Notes on how to use the I2C Module as a slave? (Only found information for master-mode).

 

On the I2C Bus there is always communication between different devices. Could it be a Problem when for the I2C Module when it gets connected to the bus within a  running transmission?

 

I hope I described my problem in good way and you can help me with it.

 

  • Josef Kohler12051 said:

    When DM355 blocks the I2C-Bus, there is no ICRDY-Interrrupt after the AAS-Interrupt (but ICIMR is set to 0x7F).
    So what is happening here?

    - The ICSTR register content might help you to debug further to identify what is occuring. For example you can see that the BB bit is set.
    As a workaround try to do a SW reset and reconfigure the I2C to see it helps to got out of this state.
    Also you might want to use a I2C bus analyzer to understand better what is happening on the bus itself.

    Josef Kohler12051 said:
    Are there any Application-Notes on how to use the I2C Module as a slave? (Only found information for master-mode).

    - All the available documentation for I2C is provided as part of the DM35x I2C Reference Guide - SPRUEE0A:
    http://www.ti.com/product/tms320dm355
    We unfortunately do not have specific documentation or application note about I2C in slave mode. The I2C controller is mostly operating in master mode but can as well operate in slave mode (as required by the I2C standard).

    Josef Kohler12051 said:
    On the I2C Bus there is always communication between different devices. Could it be a Problem when for the I2C Module when it gets connected to the bus within a  running transmission?

    As soon as the I2C controller is programmed and operational it should be able to act depending on what it sees on the bus.
    You need to refer to the I2C specification to see if there are some specific care about at start up.

    Some stuff that might help to debug further:

    - From the Linux side there are some user side code like the i2cutils SW package that could be used too to access I2C from the user's space. May be it can help for the debugging:
    https://www.ridgerun.com/developer/wiki/index.php/Developing_a_Linux_driver_for_a_chip_with_I2C_registers
    https://www.ridgerun.com/developer/wiki/index.php/Configuring_Aptina_MT9P031_using_i2c-tools
    It is not provided in the TI DVSDK but you can probably build it again for DM355.

    - It might be easier to use none OS based code to debug and isolate the behavior (especially if the issue is at the HW level).
    There are some BSL code provided by Spectrum digital for their DM355 EVM as part of the DM355 EVM Target Content. Some I2C C fct are available in the evmdm355_i2c.c file to use it as master:
    http://c6000.spectrumdigital.com/evmdm355/reve/
    It requires that you use a JTAG emulator and the TI CCS IDE to build the project and load it in the target.
    Also some other JTAG emulator (like BDI2000) and IDE (like IAR) can probably be used.

    Hope it helps.

    Anthony

  • AnBer said:

    - The ICSTR register content might help you to debug further to identify what is occuring. For example you can see that the BB bit is set.
    As a workaround try to do a SW reset and reconfigure the I2C to see it helps to got out of this state.
    Also you might want to use a I2C bus analyzer to understand better what is happening on the bus itself.

    Thanks for the response Anthony. These are the same ideas I had myself. I know of the ICSTR register and about your example: BB bit is set because I read the ICSTR register while the AAS Interrrupt occoured. In slave mode, BB can only be reset by a "Stop" on the bus oder a reset of the i2c-module. I did try to reset the i2c-module after it got stuck, but the result was a complete reset oft the whole system (?!?). Tried to use a bus analyzer, but my scope seems to be more usefull for me.

    AnBer said:

    As soon as the I2C controller is programmed and operational it should be able to act depending on what it sees on the bus.
    You need to refer to the I2C specification to see if there are some specific care about at start up.

    Thats the problem. It detects its own address, but sometimes after that, there is no RDR interrupt.

    We tryed to create a workaround like that:

    Instead of call the DM355 by

    Start - Slaveaddress - Subadress.... Stop

    we do

    Start - Slaveaddress - Stop - Start - Slaveaddress - Subaddress .... Stop

    It looks to me like the i2c module is some sort of statemachine. If the state change after receiving its own address fails, it will be recoverd by the Stop-condition. We did a lot of testing and our workaround seems to work, but how can we be sure?

    AnBer said:


    Some stuff that might help to debug further:

    - From the Linux side there are some user side code like the i2cutils SW package that could be used too to access I2C from the user's space. May be it can help for the debugging:
    https://www.ridgerun.com/developer/wiki/index.php/Developing_a_Linux_driver_for_a_chip_with_I2C_registers
    https://www.ridgerun.com/developer/wiki/index.php/Configuring_Aptina_MT9P031_using_i2c-tools
    It is not provided in the TI DVSDK but you can probably build it again for DM355.

    - It might be easier to use none OS based code to debug and isolate the behavior (especially if the issue is at the HW level).
    There are some BSL code provided by Spectrum digital for their DM355 EVM as part of the DM355 EVM Target Content. Some I2C C fct are available in the evmdm355_i2c.c file to use it as master:
    http://c6000.spectrumdigital.com/evmdm355/reve/
    It requires that you use a JTAG emulator and the TI CCS IDE to build the project and load it in the target.
    Also some other JTAG emulator (like BDI2000) and IDE (like IAR) can probably be used.

    Thanks for the links. I will check them, but looks like they are only for master mode.

  • Josef Kohler12051 said:

    we do

    Start - Slaveaddress - Stop - Start - Slaveaddress - Subaddress .... Stop

    It looks to me like the i2c module is some sort of statemachine. If the state change after receiving its own address fails, it will be recoverd by the Stop-condition. We did a lot of testing and our workaround seems to work, but how can we be sure?

    You need to thouroughly characterize this scenario in order to validate this in your design. After this you can select some tests to incorporate this as part of the production tests.

    Josef Kohler12051 said:
    Thanks for the links. I will check them, but looks like they are only for master mode.



    You are right, this none OS based C examples are for master mode. Still you can modify them accordingly for the scenario you described above. Since those are simple test it could help to validate and characterize your worarround.

    Anthony

  • Thanks for the reply Anthony.

    Apart of further tests, can you give me some Information about what is happening within the I2C module? As I have already written, my problem is an Interrupt that sometimes does not occour. This is something I do not understand, as the the config of the module is always the same. I have read the specc of the module twice and it does not give much information about slave mode.