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.

TMS320F280025C: driverlib I2C read does not write register address

Part Number: TMS320F280025C

I'm trying to read out a hall effect sensor via I2C. I've based my code on the driverlib example i2c_ex5_master_slave_interrupt.c, example 2.

I can see on my Saleae logic analyzer that the writes are correct. However, when I try to read, the sensor address is put on the bus correctly, but the register address is not. It is left high, while the clock is pulsed.

saleae analysis

The following code generates this sequence:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "i2cLib_FIFO_master_slave_interrupt.h"
//
// Defines
//
#define I2CA_SENSORADDRESS 0x35
#define I2CA_ADDRESS 0x30
#define I2CB_ADDRESS 0x40
//
// Globals
//
uint16_t status = 0;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

I did have to change the I2C_MasterReceiver() Code (creating and calling a I2C_TransmitSlaveAddress_ControlBytes_MasterReadBit() Method which sets I2C_MASTER_RECEIVE_MODE instead of I2C_MASTER_SEND_MODE) to send the read bit high, as the write bit was hardcoded, which did work.

I'm expecting 0x0 + ACK on the bus, but I get OxFF + NACK. The readout should look like this:

i2c protocol for readout

  • Hi,

    When I2C is in Read mode, I2C master doesn't transmit any more bytes. It just expects data from I2C slave. The reason why you read 0xFF is because sensor didn't transmit anything and the pull-up resistor pull the pins high.

    I did have to change the I2C_MasterReceiver() Code (creating and calling a I2C_TransmitSlaveAddress_ControlBytes_MasterReadBit() Method which sets I2C_MASTER_RECEIVE_MODE instead of I2C_MASTER_SEND_MODE) to send the read bit high, as the write bit was hardcoded, which did work.

    Revert back to original I2C_MasterReceiver code and try the below method.

    I2CA.NumOfDataBytes = 1; //Number of bytes to be received

    I2CA_ControlAddr         = 0; //Trigger bits + Register address

    status = I2C_MasterReceiver(&I2CA);

    Below is how the waveform would look like:

    1) START condition + SLAVE address + Write bit + Wait for ACK from I2C slave

    2) Transmit 1 byte (Trigger bits + Register address) + Wait for ACK from I2C slave

    3) Repeated START condition + SLAVE address + Read bit+ Wait for ACK from I2C slave.

    4) Receive data byte from slave + Send ACK from master to slave.

    5) Generate STOP condition

    Regards,

    Manoj

  • Hi Manoj,

    thanks for your reply. I've tried reverting back to the original code. However, only the sensor address in write mode and 0x00 is sent (and acknowledged). No repeated START or anything after step 2 is visible on the bus (and the clock is not pulsed after the 0x00 write). Should all of the waveform steps 1-5 above be generated by the single call to I2C_MasterReceiver()?

  • Alke,

    Should all of the waveform steps 1-5 above be generated by the single call to I2C_MasterReceiver()?

    Yes, that right!

    In example i2c_ex6_eeprom_interrupt.c, it shows the example of I2C_MasterReceiver function. Here I have 2 address bytes both 0s before I send repeated START to read a byte.

    In your case, you need to have  EEPROM.NumOfAddrBytes       = 1 and set ControlAddr = Trigger bit + Register address and run I2C_MasterReceiver(&EEPROM).

        EEPROM.currentHandlePtr     = &EEPROM;
        EEPROM.SlaveAddr            = EEPROM_SLAVE_ADDRESS;
        EEPROM.WriteCycleTime_in_us = 10000;    //6ms for EEPROM this code was tested
        EEPROM.base                 = I2CA_BASE;
        EEPROM.pControlAddr         = &ControlAddr;
        EEPROM.NumOfAddrBytes       = 2;

        //Example 2: EEPROM Byte Read
        //Make sure 11 is written to EEPROM address 0x0
        ControlAddr = 0;
        EEPROM.pControlAddr   = &ControlAddr;
        EEPROM.pRX_MsgBuffer  = RX_MsgBuffer;
        EEPROM.NumOfDataBytes = 1;

        status = I2C_MasterReceiver(&EEPROM);

    Regards,

    Manoj