<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>IÂ²C unexpected behaviour</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/35072/ia2c-unexpected-behaviour</link><description> 
Hi folks, 

 
I&amp;#39;m trying to read a constant voltage through the MCP3425 ADC
connected to a LPC1768 microcontroller, using the i2c 1 port. My code
is based in one of the Keil i2c usage examples. 
I&amp;#39;m getting a very strange behaviour, I ended up stucked</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: IÂ²C unexpected behaviour</title><link>https://community.arm.com/thread/70722?ContentTypeID=1</link><pubDate>Mon, 30 Apr 2018 10:31:27 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:8da55e27-cb4e-4229-9aa0-84e9942790b9</guid><dc:creator>Victor Santos</dc:creator><description>&lt;p&gt;&lt;p&gt;
i2c.c&lt;/p&gt;

&lt;pre&gt;

#include &amp;quot;lpc17xx.h&amp;quot;
#include &amp;quot;type.h&amp;quot;
#include &amp;quot;i2c.h&amp;quot;

volatile uint32_t I2CMasterState[I2C_PORT_NUM] = {I2C_IDLE,I2C_IDLE,I2C_IDLE};
volatile uint32_t timeout[I2C_PORT_NUM] = {0, 0, 0};

volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
volatile uint32_t I2CCount[I2C_PORT_NUM] = {0, 0, 0};
volatile uint32_t I2CReadLength[I2C_PORT_NUM];
volatile uint32_t I2CWriteLength[I2C_PORT_NUM];

volatile uint32_t RdIndex0 = 0, RdIndex1 = 0, RdIndex2 = 0;
volatile uint32_t WrIndex0 = 0, WrIndex1 = 0, WrIndex2 = 0;


void I2C1_IRQHandler(void)
{
  uint8_t StatValue;

  timeout[1] = 0;
  /* this handler deals with master read and master write only */
  StatValue = LPC_I2C1-&amp;gt;I2STAT;
  switch ( StatValue )
  {
        case 0x08:                      /* A Start condition is issued. */
        WrIndex1 = 0;
        LPC_I2C1-&amp;gt;I2DAT = I2CMasterBuffer[1][WrIndex1++];
        LPC_I2C1-&amp;gt;I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
        break;

        case 0x10:                      /* A repeated started is issued */
        RdIndex1 = 0;
        /* Send SLA with R bit set, */
        LPC_I2C1-&amp;gt;I2DAT = I2CMasterBuffer[1][WrIndex1++];
        LPC_I2C1-&amp;gt;I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
        break;

        case 0x18:                      /* Regardless, it&amp;#39;s a ACK */
        if ( I2CWriteLength[1] == 1 )
        {
          LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_STO;      /* Set Stop flag */
          I2CMasterState[1] = I2C_NO_DATA;
        }
        else
        {
          LPC_I2C1-&amp;gt;I2DAT = I2CMasterBuffer[1][WrIndex1++];
        }
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;
        break;

        case 0x28:      /* Data byte has been transmitted, regardless ACK or NACK */
        if ( WrIndex1 &amp;lt; I2CWriteLength[1] )
        {
          LPC_I2C1-&amp;gt;I2DAT = I2CMasterBuffer[1][WrIndex1++]; /* this should be the last one */
        }
        else
        {
          if ( I2CReadLength[1] != 0 )
          {
                LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_STA;   /* Set Repeated-start flag */
          }
          else
          {
                LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_STO;      /* Set Stop flag */
                I2CMasterState[1] = I2C_OK;
          }
        }
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;
        break;

        case 0x30:
        LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_STO;      /* Set Stop flag */
        I2CMasterState[1] = I2C_NACK_ON_DATA;
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;
        break;

        case 0x40:      /* Master Receive, SLA_R has been sent */
        if ( (RdIndex1 + 1) &amp;lt; I2CReadLength[1] )
        {
          /* Will go to State 0x50 */
          LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_AA;  /* assert ACK after data is received */
        }
        else
        {
          /* Will go to State 0x58 */
          LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_AAC; /* assert NACK after data is received */
        }
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;
        break;

        case 0x50:      /* Data byte has been received, regardless following ACK or NACK */
        I2CSlaveBuffer[1][RdIndex1++] = LPC_I2C1-&amp;gt;I2DAT;
        if ( (RdIndex1 + 1) &amp;lt; I2CReadLength[1] )
        {
          LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_AA;  /* assert ACK after data is received */
        }
        else
        {
          LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_AAC; /* assert NACK on last byte */
        }
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;
        break;

        case 0x58:
        I2CSlaveBuffer[1][RdIndex1++] = LPC_I2C1-&amp;gt;I2DAT;
        I2CMasterState[1] = I2C_OK;
        LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_STO;   /* Set Stop flag */
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;   /* Clear SI flag */
        break;

        case 0x20:              /* regardless, it&amp;#39;s a NACK */
        case 0x48:
        LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_STO;      /* Set Stop flag */
        I2CMasterState[1] = I2C_NACK_ON_ADDRESS;
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;
        break;

        case 0x38:              /* Arbitration lost, in this example, we don&amp;#39;t
                                        deal with multiple master situation */
        default:
        I2CMasterState[1] = I2C_ARBITRATION_LOST;
        LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_SIC;
        break;
  }
  return;
}

uint32_t I2CStart( uint32_t portNum )
{
  uint32_t retVal = FALSE;

  timeout[portNum] = 0;
  /*--- Issue a start condition ---*/
  LPC_I2C[portNum]-&amp;gt;I2CONSET = I2CONSET_STA; /* Set Start flag */

  /*--- Wait until START transmitted ---*/
  while( 1 )
  {
        if ( I2CMasterState[portNum] == I2C_STARTED )
        {
          retVal = TRUE;
          break;
        }
        if ( timeout[portNum] &amp;gt;= MAX_TIMEOUT )
        {
          retVal = FALSE;
          break;
        }
        timeout[portNum]++;
  }
  return( retVal );
}

uint32_t I2CStop( uint32_t portNum )
{
  LPC_I2C[portNum]-&amp;gt;I2CONSET = I2CONSET_STO;      /* Set Stop flag */
  LPC_I2C[portNum]-&amp;gt;I2CONCLR = I2CONCLR_SIC;  /* Clear SI flag */

  /*--- Wait for STOP detected ---*/
  while( LPC_I2C[portNum]-&amp;gt;I2CONSET &amp;amp; I2CONSET_STO );
  return TRUE;
}

void I2C1Init( void )
{
  LPC_SC-&amp;gt;PCONP |= (1 &amp;lt;&amp;lt; 19);

#if 0
  /* set PIO0.0 and PIO0.1 to I2C1 SDA and SCL */
  /* function to 11 on both SDA and SCL. */
  LPC_PINCON-&amp;gt;PINSEL0 &amp;amp;= ~((0x3&amp;lt;&amp;lt;0)|(0x3&amp;lt;&amp;lt;2));
  LPC_PINCON-&amp;gt;PINSEL0 |= ((0x3&amp;lt;&amp;lt;0)|(0x3&amp;lt;&amp;lt;2));
  LPC_PINCON-&amp;gt;PINMODE0 &amp;amp;= ~((0x3&amp;lt;&amp;lt;0)|(0x3&amp;lt;&amp;lt;2));
  LPC_PINCON-&amp;gt;PINMODE0 |= ((0x2&amp;lt;&amp;lt;0)|(0x2&amp;lt;&amp;lt;2));           /* No pull-up no pull-down */
  LPC_PINCON-&amp;gt;PINMODE_OD0 |= ((0x01&amp;lt;&amp;lt;0)|(0x1&amp;lt;&amp;lt;1));       /* Open drain */
#endif
#if 1
  /* set PIO0.19 and PIO0.20 to I2C1 SDA and SCL */
  /* function to 11 on both SDA and SCL. */

 LPC_PINCON-&amp;gt;PINSEL1 = 0;
  LPC_PINCON-&amp;gt;PINSEL1 |= 0x3C0;
  LPC_PINCON-&amp;gt;PINMODE1 = 0;
  LPC_PINCON-&amp;gt;PINMODE1 |= 0x280;     /* No pull-up no pull-down */
  LPC_PINCON-&amp;gt;PINMODE_OD0 |= ((0x1&amp;lt;&amp;lt;19)|(0x1&amp;lt;&amp;lt;20));

#endif

  /*--- Clear flags ---*/
  LPC_I2C1-&amp;gt;I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;

  /*--- Reset registers ---*/
  LPC_I2C1-&amp;gt;I2SCLL   = I2SCLL_SCLL;
  LPC_I2C1-&amp;gt;I2SCLH   = I2SCLH_SCLH;

  /* Install interrupt handler */
  NVIC_EnableIRQ(I2C1_IRQn);

  LPC_I2C1-&amp;gt;I2CONSET = I2CONSET_I2EN;
  return;
}

uint32_t I2CEngine( uint32_t portNum )
{
  /*--- Issue a start condition ---*/
  LPC_I2C[portNum]-&amp;gt;I2CONSET = I2CONSET_STA; /* Set Start flag */

  I2CMasterState[portNum] = I2C_BUSY;

  while ( I2CMasterState[portNum] == I2C_BUSY )
  {
        if ( timeout[portNum] &amp;gt;= MAX_TIMEOUT )
        {
          I2CMasterState[portNum] = I2C_TIME_OUT;
          break;
        }
        timeout[portNum]++;
  }
  LPC_I2C[portNum]-&amp;gt;I2CONCLR = I2CONCLR_STAC;

  return ( I2CMasterState[portNum] );
}



&lt;/pre&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>