I2C experience

Hi all,

I’ve been trying for past few days to make I2C work on a SL6087. I’m writing this in the hopes that you’ll find it when you need it. I’m only using synchronous access (no interrupts etc.)

Just like everyone else, I’ve been getting ADL_RET_ERR_PARAM on both adl_busRead and adl_busWrite. It seems that this error code is returned in several cases:

  • One or both of the GPIOs are used elsewhere (note that the adl_busSubscribe function succeeds!)
  • The bus is busy (SDA or SCL is held low)
  • The chip address is wrong
  • The pAccessMode is NULL

It is also possible to generate a Repeat condition using the pAccessMode.address: you can write 1-4 bytes to the bus, then a repeat condition is set, then you can read or write as many bytes as you want.

Notes on the code: I’ve removed all error checking to keep it short. Also it uses local variables in adl_busRead and Write because I’m using synchronous mode. Feel free to add some buffers and wm_memmove()s.

const adl_busI2CSettings_t DefaultBusGpsSettings=
  0x00000084>>1, //chip address = 0x84
int addressLength=0;
s32 busI2CGpsHandle=-1;

void i2cOpen()
  adl_busI2CSettings_t busGpsSettings;
  wm_memmove(&busGpsSettings, &DefaultBusGpsSettings, sizeof(busGpsSettings));
  busI2CGpsHandle=adl_busSubscribe(ADL_BUS_ID_I2C, 1, (adl_busSettings_u *)&busGpsSettings);

void i2cClose()
  adl_busIOCtl(busI2CGpsHandle, ADL_BUS_CMD_RESET_BLOC, 0); //seems to help here and there :-/

adl_busAccess_t i2cAccessR=
  0xFD000000, //used: SET_ADD_SIZE 8
  0 //ignored for I2C
adl_busAccess_t i2cAccessW=
  0xFF000000, //ignored: SET_ADD_SIZE 0
  0 //ignored for I2C

int i2cSendRecv(int wrlen, u8 *wrdata, int rdlen, u8 *rddata)
  //write 'wrdata' data only
  adl_busIOCtl(busI2CGpsHandle, ADL_BUS_CMD_SET_ADD_SIZE, &addressLength);
  adl_busWrite(busI2CGpsHandle, &i2cAccessW, wrlen, wrdata);
  //write 1 byte '\xFD', repeat condition, then read 'rdlen' bytes
  adl_busIOCtl(busI2CGpsHandle, ADL_BUS_CMD_SET_ADD_SIZE, &addressLength);
  adl_busRead(busI2CGpsHandle, &i2cAccessR, rdlen, rddata);

  return 0;

Hi milan,
Thanks for sharing this… :smiley: