lpcware

Help communicating with I2C octal registers and switches

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by jtor on Fri Feb 06 12:54:25 MST 2015
Hi everyone,

I have an LPC2368 with a Keil Dev Board.  I am needing assistance in reading a couple I2C devices.

I have been trying to communicate with a PCA9557 as well as a PCA9547D both made by NXP.  Listed below are links to the data sheets. 

www.nxp.com/documents/data_sheet/PCA9557.pdf - pg. 9 of 30

http://www.nxp.com/documents/data_sheet/PCA9547.pdf - pg. 6 of 30


When configuring and reading these registers, my status bits are returning okay, but my expected output buffers are not accurate.

I want to know if my method of communicating with these specific devices is correct, which I do not think so..  To illustrate this, I am going to have to post some code.


//CONFIGURE REGISTER PORTION
uint8 configOctalRegister(void)
{
uint8 stat;
uint8 buff[2] = { 0x03, 0x7F }; // 0x03 = CONIG REGISTER, 0x7F = pins 1 - 6 are inputs and pin 7 is an output

stat = writeI2C( ADDR_1, 2, buff, 1 ); //octalRegister1

return stat;
}


int writeI2C(uint8 addr, uint8 sz, uint8 *buff, uint8 bus)
{
  uint8 i;
  uint16 stat;

  /* shift address to bits 7-1; bit 0 is R/W */
  I2CMasterBuffer[0] = addr<<1;

  /* write "size" + 1 uint8 for address */
  I2CWrLength = sz + 1;
  I2CRdLength = 0;
  for (i = 0; i < sz; i++)
I2CMasterBuffer[i+1] = buff;
   
  stat = I2CEngine(bus);
  return stat;
}


I will now show the process of how I read the input register.  My I2C master buffer is this, in order, [0] = ADDR ; [1] = 0x00 (input reg) ; [2] = READ ADDR


uint8 readExpanderPins( uint8 addr)
{
uint8 stat;
uint8 buff;
        buff = 0x00; //read the input port register

        stat = write_readI2C( ADDR_1, 1, 0x00, &buff, 1 );  //passing the addr, readSize, offset, buffer, bus
if(!stat)
{
bit2status = ( buff & 0x04 ); //buff[2]; bit2
bit3tatus = ( buff & 0x08 ); //buff[3]; bit3
bit4status = ( buff & 0x01 ); //buff[4]; bit4
bit5status = ( buff & 0x20 ); //buff[5]; bit5
bit6status = ( buff & 0x40 ); //buff[6]; bit6
}
return stat;



int write_readI2C(uint8 addr, uint8 sz, uint8 offset, uint8 *buff, uint8 bus)
{
  uint8 i;
  uint16 stat;

  /* shift address to bits 7-1; bit 0 is R/W */
  I2CMasterBuffer[0] = addr<<1;

  /* write 2 size: I2C address + offset to read */
  I2CWrLength = 2;
  I2CMasterBuffer[1] = offset;
   
  /* now load read command */
  I2CMasterBuffer[2] = addr<<1 | RD_BIT;
  I2CRdLength = sz;

  stat = I2CEngine(bus);
  if (stat)
    return stat;

  if (RdIndex == 0) //no data was read
return FAIL; //(I2C_ERR_MASK | RD_ERR);
  for ( i = 0; i < sz; i++ )
    buff = I2CMasterBuffer[i+3];

  return stat;
}


I will not show the interrupt routine soloely based on I know it works for reading and writing to other I2C devices such as temperature sensor.  Plus this post is already long enough.

I appreciate any expert help on my problem.  If any more content is needed just let me know.

Outcomes