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
ADL_BUS_I2C_CLK_STD, //_STD, _FAST, _HIGH
ADL_BUS_I2C_ADDR_7_BITS,
ADL_BUS_I2C_MASTER_MODE
};
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_busUnsubscribe(busI2CGpsHandle);
busI2CGpsHandle=-1;
}
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
addressLength=0*8;
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
addressLength=1*8;
adl_busIOCtl(busI2CGpsHandle, ADL_BUS_CMD_SET_ADD_SIZE, &addressLength);
adl_busRead(busI2CGpsHandle, &i2cAccessR, rdlen, rddata);
return 0;
}