This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DRV10987: I2C read error

Part Number: DRV10987
Other Parts Discussed in Thread: DRV10983,

Hello

I used DRV10983 before, and via I2C interface, can read various register's value properly.

But after change to DRV10987, I couldn't read any register's value.

The two device's addresses are same as 101 0010b.

But each registers are different not only address but register data wide.

So I followed 'I2C serial interface' of datasheet and some test result waveform in this forum (e2e.ti.com/.../737265

But basically, both I2C protocols are different so I'm still confusing.

Even I tried both way, still not success to get register value.

Here is my code & oscilloscope waveform.

Please let me know which mistake I did.

Thanks.

-----------------------------------------------------------------------------------------------------------------------------------------

#define DRV_ADDR 0xA4 // DRV10983 I2C Slave Address Write [0b1010 010x - x: write(0) & read(1)]
#define CONFIG_3 0x92 // Configuration 3 Register [bit 7:6 - OpenCurr | 20W: 10 | 45W: 11]

void I2C_Start(void)
{
SDA = 1;

SDA_DIR = OUT; BUS_DIR = 1; delay_us(10);

SDA = 1; delay_us(10);
SCL = 1; delay_us(10);
SDA = 0; delay_us(10);
SCL = 0; delay_us(10);
}

void I2C_Stop(void)
{
SDA_DIR = OUT; BUS_DIR = 1; delay_us(10);

SDA = 0; delay_us(10);
SCL = 1; delay_us(10);
SDA = 1; delay_us(10);
SCL = 0; delay_us(10);
}

void I2C_Ack_Recieve(void)
{
SDA_DIR = IN; BUS_DIR = 0; delay_us(10);

SCL = 1; delay_us(10);
SCL = 0; delay_us(10);
}

void I2C_Ack_Transmit(void)
{
SDA = 0;

SDA_DIR = OUT; BUS_DIR = 1; delay_us(10);

SCL = 1; delay_us(10);
SCL = 0; delay_us(10);
}

void I2C_Nak_Transmit(void)
{
SDA = 1;

SDA_DIR = OUT; BUS_DIR = 1; delay_us(10);

SCL = 1; delay_us(10);
SCL = 0; delay_us(10);
}

void I2C_Write(unsigned char data)
{
unsigned char i;

SDA_DIR = OUT; BUS_DIR = 1; delay_us(10);

SCL = 0; delay_us(10);

// 8bit transmit
for(i=0;i<8;i++)
{
// Send fron MSB
if(((0x80 >> i) & data) == 0) SDA = 0;
else SDA = 1;
delay_us(10);

SCL = 1; delay_us(10);
SCL = 0;
}
}

unsigned char I2C_Read_Format(unsigned char device, unsigned char address)
{
unsigned char i;
unsigned char value;

I2C_Start();
I2C_Write(device);
I2C_Ack_Recieve();
I2C_Write(address);
I2C_Ack_Recieve();
I2C_Start();
I2C_Write(device | 0x01);
I2C_Ack_Recieve();

//////////////////////////////////////////////////////////

SDA_DIR = IN; BUS_DIR = 0; delay_us(10);

value = 0;

// Upper 8bit recieve
for(i=0;i<8;i++)
{
SCL = 1; delay_us(10);
SCL = 0; delay_us(10);
}

I2C_Ack_Transmit();

//////////////////////////////////////////////////////////

SDA_DIR = IN; BUS_DIR = 0; delay_us(10);

// Lower 8bit recieve
for(i=0;i<8;i++)
{
SCL = 1; delay_us(10);

if(SDA) value |= 0x01 << (7 - i);

SCL = 0; delay_us(10);

}

I2C_Nak_Transmit();

//////////////////////////////////////////////////////////

I2C_Stop();

return value;
}

 


  • Hello Cha Jeyong,

    Thanks for posting on the E2E forums, an expert should be reaching out to you soon. Note that there is a holiday in the US this week so I ask for your patience as there will be some delay.

    For now, please disregard the protocol and packet structure you've developed for the DRV10983. The DRV10987 uses the packet structure that you've shown from the datasheet. I suggest you try to exact match the waveform you have reference. For example, the Main (formerly known as master) is clearly stretching the clock after the I2C start has been triggered which is not what the picture above shows. For your information, clock stretching is something that is implemented by the Secondary (formerly known as slave) device.

    Best,

    -Cole

  • Hi CHA,

    Just wanted to follow-up with you to see if you have any updates?

    Regards,

    Vishnu.

  • Thanks for you reply.

    Actually, I have succeeded it some days before.

    But I forgot to inform.

    The problem was the way of access to EEPROM.

    When I use DRV10983, I just access a specific EEPROM address in direct and just read it, then could read some data.

    But DRV10987, there was several EEPROM programming registers(0x31~0x36).

    If I want to read some EEPROM area, should access to them not EEPROM directly.

    I didn't knew it.

    I just thought it was easy to approach the same as the existing DRV10983.

    Thank you for your interest.