infineon4engi@twitter infineon4engineers infineon@linkedin infineon@youtube
twitter Facebook Linkedin Youtube

+ Reply to Thread
Results 1 to 6 of 6

Thread: Initial I2C Bus Reset

  1. #1
    New Member New Member jonatan.zeidler is on a distinguished road
    Join Date
    Jul 2020
    Posts
    3
    Points
    40

    Initial I2C Bus Reset

    It happens that some I2C slave permanently pulls down SDA, after the I2C bus was interrupted during some transmission.
    A solution to this is toggling the clock 8 times and sending a stop condition. A similar solution is to perform a Nack Read without Start Condition.
    The reference manual describes such a procedure in 18.5.4.2 Valid Master Transmit Data Formats in case of a wrong TDF code.

    I would like to perform such a Bus Reset on each boot of my XMC4800. I tried with

    Code:
    XMC_I2C_CH_MasterReceiveNack(channel);
    XMC_I2C_CH_MasterStop(channel);
    after initialization. Unfortunately, in case of a stuck SDA all what happens is a single clock toggle.
    I do not even get an i2c event interrupt. So I need to boot the XMC4800 up to eight times to reset the bus.

    Is there a clean way to achieve this bus reset on initialization? Or do I need to configure the Pins as GPIO
    first and toggle the clock myself before initializing the I2C module?

  2. #2

    Infineon Employee
    Infineon Employee
    jferreira will become famous soon enough
    Join Date
    Oct 2012
    Posts
    775
    Hi,

    Can you try with the following sequence?
    Code:
          XMC_I2C_CH_ClearStatusFlag(i2c->i2c, XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);
          // Clear the bus by sending nine clock pulses
          XMC_I2C_CH_MasterStart(i2c->i2c, 0xff, XMC_I2C_CH_CMD_READ);
          while ((XMC_I2C_CH_GetStatusFlag(i2c->i2c) & XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U)
          ;
    
          XMC_I2C_CH_ClearStatusFlag(i2c->i2c, XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);
          XMC_I2C_CH_MasterStop(i2c->i2c);
          while ((XMC_I2C_CH_GetStatusFlag(i2c->i2c) & XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U)
          ;
    Regards,
    Jesus
    The views expressed here are my personal opinions, have not been reviewed or authorized by Infineon and do not necessarily represent the views of Infineon.

  3. #3
    New Member New Member jonatan.zeidler is on a distinguished road
    Join Date
    Jul 2020
    Posts
    3
    Points
    40
    Thanks for the reply. Unfortunately the suggested solution does not work for me. In case no slave holds down SDA I can see the clock toggles. But if a slave holds SDA, the clock is not toggled even once and the code remains in the first loop waiting for XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION for ever.

  4. #4

    Infineon Employee
    Infineon Employee
    jferreira will become famous soon enough
    Join Date
    Oct 2012
    Posts
    775
    Hi,

    I cannot check right now, but maybe you could try:

    Code:
          
          XMC_I2C_CH_SetInputSource(i2c->i2c, XMC_I2C_CH_INPUT_SDA, USIC_INPUT_ALWAYS_1);
    
          XMC_I2C_CH_ClearStatusFlag(i2c->i2c, XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);
          // Clear the bus by sending nine clock pulses
          XMC_I2C_CH_MasterStart(i2c->i2c, 0xff, XMC_I2C_CH_CMD_READ);
          while ((XMC_I2C_CH_GetStatusFlag(i2c->i2c) & XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U)
          ;
    
          XMC_I2C_CH_ClearStatusFlag(i2c->i2c, XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);
          XMC_I2C_CH_MasterStop(i2c->i2c);
          while ((XMC_I2C_CH_GetStatusFlag(i2c->i2c) & XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U)
          ;
    
          XMC_I2C_CH_SetInputSource(i2c->i2c, XMC_I2C_CH_INPUT_SDA, i2c->sda_pin_input);
    Regards,
    Jesus
    The views expressed here are my personal opinions, have not been reviewed or authorized by Infineon and do not necessarily represent the views of Infineon.

  5. #5

    Infineon Employee
    Infineon Employee
    jferreira will become famous soon enough
    Join Date
    Oct 2012
    Posts
    775
    Hi,

    I have being trying it out and finally you need to do something like

    Code:
      XMC_GPIO_SetMode(SDA_PIN, XMC_GPIO_MODE_INPUT_TRISTATE);
      XMC_I2C_CH_SetInputSource(I2C_CHANNEL, XMC_I2C_CH_INPUT_SDA1, USIC0_C0_DX3_DOUT0);
    
      do
      {
        XMC_I2C_CH_SetInputSource(I2C_CHANNEL, XMC_I2C_CH_INPUT_SDA, USIC0_C0_DX0_DX3INS);
    
        XMC_I2C_CH_ClearStatusFlag(I2C_CHANNEL, XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);
        // Clear the bus by sending nine clock pulses
        XMC_I2C_CH_MasterStart(I2C_CHANNEL, 0xff, XMC_I2C_CH_CMD_READ);
        while ((XMC_I2C_CH_GetStatusFlag(I2C_CHANNEL) & XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U);
    
        // Not Acknowledge software recovery since operating in Loop Back Mode
        XMC_USIC_CH_TXFIFO_Flush(I2C_CHANNEL);
        XMC_USIC_CH_TXFIFO_Flush(I2C_CHANNEL);
        XMC_USIC_CH_SetTransmitBufferStatus(I2C_CHANNEL, XMC_USIC_CH_TBUF_STATUS_SET_IDLE);
        XMC_I2C_CH_ClearStatusFlag(I2C_CHANNEL, 0x1ffff);
    
        XMC_I2C_CH_SetInputSource(I2C_CHANNEL, XMC_I2C_CH_INPUT_SDA, USIC0_C0_DX0_P2_1);
      }
      while (XMC_GPIO_GetInput(SDA_PIN) == 0);
    The views expressed here are my personal opinions, have not been reviewed or authorized by Infineon and do not necessarily represent the views of Infineon.

  6. #6
    New Member New Member jonatan.zeidler is on a distinguished road
    Join Date
    Jul 2020
    Posts
    3
    Points
    40
    I just implemented a solution using the GPIO interface before configuring the I2C interface. Thanks anyway for the pure-I2C-interface-solution you just provided.

+ Reply to Thread

Tags for this Thread

Disclaimer

All content and materials on this site are provided “as is“. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.