lpcware

LPC1768 I2C - Setting of I2EN requires a delay of at least 4uS before I2C is usable ????

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by MarkSBoyce on Fri Jan 01 02:42:09 MST 2016
Using CMSIS sample code I successfully executed an I2C Transfer on my LPC Dev board.

After importing a simplified example of the C code into my existing project I struggled to correctly initialise I2C 0 (I2C0)

After initialisation I attempted to Send a START command with the address of my device. The SDA line dropped to 0 followed by the CLK line 10uS Later. However the clock did not continue to run but remained low for the duration.

After many many hours I found by delaying my code by about 4uS after setting I2EN the clock did in fact run and all was well.

I then removed the delays in the original CMSIS sample code (delays waiting for user input etc) and the same problem occurred.

There is nothing in the LPC17xx User Manual about there requiring a delay or in fact anything in Newsgroups.

Any idea's please.

Mark

See code snipped below:




    U32 i2c_init()
    {
                                             //30 28 26 24  22 20 00 00
    #define I2C0_PINS 0x01400000 // 0140 0000  = 00 00 00 01  01 00 00 00
      // Configure Port 0:27 SDA & 0:28 CLK
      LPC_PINCON->PINSEL1 &= ~0x03C00000;
      LPC_PINCON->PINSEL1 |= I2C0_PINS;


      // Configure Port 0:27 and 0:28 as Standard Drive Mode with Slew Rate and Glitch Control enabled
      LPC_PINCON->I2CPADCFG = 0x00;



      // Set up clock and power for I2C0 module
      LPC_SC->PCONP |=  0x00000080 & CLKPWR_PCONP_BITMASK;  //bit 7 = I2C0
 
      // Peripheral clock has been configured to 25MHz
      // Set the I2C clock value to register 25MHz / 100kHz = 250 full cycle or 125 for half cycle

      LPC_I2C0->I2SCLH = (uint32_t)(125);  // Duty Cycle of High Clock 100kHz
      LPC_I2C0->I2SCLL = (uint32_t)(125);  // Duty Cycle of Low Clock 100kHz

      // Set I2C operation to default
      LPC_I2C0->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC |    I2C_I2CONCLR_I2ENC);  // Disable I2C Interface (bit 6) Clear Start Bit (Bit 5)   Clear Acknowledge (Bit 2)


      //Do a dummy transmit for logic Analyser test
      LPC_I2C0->I2CONSET = I2C_I2CONSET_I2EN; // Enable I2C Interface (Bit 6)
      delay_us(4); // No I2C clock is visible if Set to 3uS or less from setting of I2EN
 
      LPC_I2C0->I2CONSET = I2C_I2CONSET_STA;
      LPC_I2C0->I2CONCLR = I2C_I2CONCLR_SIC;

      LPC_I2C0->I2DAT = 0xA0;
      // Wait for complete
      while (!(LPC_I2C0->I2CONSET & I2C_I2CONSET_SI));
      LPC_I2C0->I2CONCLR = I2C_I2CONCLR_STAC;
      return (LPC_I2C0->I2STAT & I2C_STAT_CODE_BITMASK);
    }

Outcomes