Hi all
I need to perform a read from a slave device where I first send the device address and subaddress as a write then a repeated start to read in the data.
The write works OK and the clock line stays low because set_stop is not set, but the repeated start doesn't happen. There is no activity on the clock or data line.
I'm calling I2C_write followed by I2C_read:
Both work fine individually. For this case, both set_stop and chk_busy are set to 0.
Any ideas??
Thanks,
Clive
uint32_t I2C_write(i2c_regs_t *i2c, uint16_t in_addr, uint8_t *src_buffer, uint16_t in_length, uint8_t set_stop) } uint32_t I2C_read(i2c_regs_t *i2c, uint16_t in_addr, uint8_t *dest_buffer, uint16_t in_length, uint8_t chk_busy)
{
uint32_t rtn = ERR_INVALID_PARAMETER;
if ((i2c != NULL) && (src_buffer != NULL))
{
uint16_t i;
// wait for bus to be clear.
WAIT_WITH_TIMEOUT(CHKBIT(i2c->ICSTR, BB), I2C_TIMEOUT_COUNT);
// set byte count and slave address.
i2c->ICCNT = in_length;
i2c->ICSAR = in_addr;
// configure i2c for master transmit mode and release from reset.
i2c->ICMDR = STT | MST | ICMDR_FREE | TRX | IRS;
// transmit data one byte at a time.
for (i = 0; i < in_length; i++)
{
i2c->ICDXR = src_buffer[i];
// wait for data to be copied to shift register.
WAIT_WITH_TIMEOUT(!CHKBIT(i2c->ICSTR, ICXRDY), I2C_TIMEOUT_COUNT);
}
// send stop condition...we may want to skip this depending on which
// device we are talking to. see device datasheets for more info.
if (set_stop)
SETBIT(i2c->ICMDR, STP);
rtn = ERR_NO_ERROR;
}
return (rtn);
{
uint32_t rtn = ERR_INVALID_PARAMETER;
if ((i2c != NULL) && (dest_buffer != NULL))
{
uint16_t i;
// wait for bus to be clear...we may want to skip this depending on which
// device we are talking to. see device datasheets for more info.
if (chk_busy)
WAIT_WITH_TIMEOUT(CHKBIT(i2c->ICSTR, BB), I2C_TIMEOUT_COUNT);
// set byte count and slave address.
i2c->ICCNT = in_length;
i2c->ICSAR = in_addr;
// configure i2c for master receive mode and release from reset.
i2c->ICMDR = STT | MST | CMDR_FREE | IRS;
// receive data one byte at a time.
for (i = 0; i < in_length; i++)
{
// do not want to send an ack on last byte.
if (i == (in_length - 1))
{
SETBIT(i2c->ICMDR, NACKMOD);
}
// wait for data to be received.
WAIT_WITH_TIMEOUT(!CHKBIT(i2c->ICSTR, ICRRDY), I2C_TIMEOUT_COUNT);
dest_buffer[i] = i2c->ICDRR;
}
// send stop condition.
SETBIT(i2c->ICMDR, STP);
rtn = ERR_NO_ERROR;
}
return (rtn);
}