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.

TMS320F28375S: not able to read I2C data from AM4096 magnetic encoder.

Part Number: TMS320F28375S
Other Parts Discussed in Thread: SYSCONFIG, , C2000WARE

Hello guys,

my code is based on TMS320F28375S and i am debugging it in Launchpad 28379D. I have configured I2C by sysconfig tool as shown in image below.

I have knowledge about I2C protocol but i don't know how it is working in ccs (TI controllers)

this is a part of my code which is used for I2C

void main()
{

    myI2C0_init();


    //-----------------------------------//
    
    // while loop from main()
    
    while(1)
    {
        while(I2C_isBusBusy(myI2C0_BASE));                      // bus check
        I2C_sendStartCondition(myI2C0_BASE);                    // start
        I2C_putData(myI2C0_BASE, 0xB4);                         // addr + 0 (write)
        I2C_putData(myI2C0_BASE, 0x20);                         // read reg no 32
        I2C_sendStartCondition(myI2C0_BASE);                    // repeated start
        I2C_putData(myI2C0_BASE, 0xB5);                         // addr + 1 (read)
        I2C_buf[0] = I2C_getData(myI2C0_BASE);                  // read MSB
        I2C_sendNACK(myI2C0_BASE);                              // send NACK
        I2C_buf[1] = I2C_getData(myI2C0_BASE);                  // read LSB
        I2C_sendNACK(myI2C0_BASE);                              // send NACK
        I2C_sendStopCondition(myI2C0_BASE);                     // stop
        while (I2C_getStopConditionStatus(myI2C0_BASE));        // stop status
    }
}

// I2C init function in Board.c file //
void myI2C0_init(){
	I2C_disableModule(myI2C0_BASE);
	I2C_initController(myI2C0_BASE, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_33);
	I2C_setConfig(myI2C0_BASE, I2C_CONTROLLER_SEND_MODE);
	I2C_setTargetAddress(myI2C0_BASE, 90);
	I2C_disableLoopback(myI2C0_BASE);
	I2C_setBitCount(myI2C0_BASE, I2C_BITCOUNT_8);
	I2C_setDataCount(myI2C0_BASE, 2);
	I2C_setAddressMode(myI2C0_BASE, I2C_ADDR_MODE_7BITS);
	I2C_disableFIFO(myI2C0_BASE);
	I2C_setEmulationMode(myI2C0_BASE, I2C_EMULATION_STOP_SCL_LOW);
	I2C_enableModule(myI2C0_BASE);
}

my slave address is 90(decimal).

the I2C is not working as per this. sometimes the bus is busy and sometimes i get stucked while getting stop conditon status.

please help me to get data from AM4096.

thanks in advance.

regards

Muzammil Qureshi

  • Hello Muzammil,

    Have you referred to the existing examples for I2C in C2000Ware? The example i2c_ex3_external_loopback shows how to use send/receive data with I2C and even has an interrupt for the I2C FIFO, I would recommend looking at it for your basic setup. Make sure you can run this example before proceeding, that way you have a known good starting point before development.

    C2000Ware_5_01_00_00\driverlib\f2837xs\examples\cpu1\i2c

  • Hello Omer,

    thanks for reply,

    In my case, i have to get data from I2C in polling mode and without FIFO mode. for that i am trying but i am not able to get the data. please suggest me further.

    I have also attached the code of how I am doing this in previous message. please provide me support related to this.

    thanks and regards

    Muzammil Qureshi

  • Hello omer,

    The clock goes in low state after the first transmission.

    thanks and regards

    Muzammil Qureshi

  • Hello Muzammil,

    In my case, i have to get data from I2C in polling mode and without FIFO mode. for that i am trying but i am not able to get the data. please suggest me further.

    In the example folder I mentioned earlier, there isn't an example without using the FIFO and polling, but i2c_ex4_eeprom_polling shows how to use I2C with polling. If you take a look at Figure 19-7. I2C Master TX / RX Flowchart in the I2C chapter of the reference manual, you can see that if you're not using FIFO or repeat mode then transmitting data only requires filling the I2CDXR register with the next data:

    In driverlib, this means using the I2C_putData to fill the register.

    Looking at your code, I'm not sure exactly what you're doing sending multiple starts without a stop. The flow diagram shows that transmitting data with/without FIFO only differs in the interrupt that would need to be polled. Are you trying to use repeat mode? If so, your I2CMDR register would not be configured correctly based on your I2C setup. It doesn't look like SysConfig has the option for repeat mode, so I'll let the software experts know to add this. In the meantime, you I2C_setConfig would need to include the I2C_REPEAT_MODE macro for using repeat mode, if that's what you intend.

    I have also attached the code of how I am doing this in previous message. please provide me support related to this.

    You stated that your code wasn't working, so I was going to cite working examples to help simplify the solution rather than correcting your code.

  • Hello Omer,

    Looking at your code, I'm not sure exactly what you're doing sending multiple starts without a stop.

    I have put start condition without stop condition because, after writing slave address and register address from which i have to read, i have to generate REPEATED START condition (which can be generated writing start condition without writing stop condition) to get the data as per the datasheet of AM4096.

    the second thing is my SDA line always goes low after first transmission.

    let me explain problem in detail.

    I am getting the data only one time and that also after connecting AM4096 encoder to its own USB hardware (UPRGAM4096) and then again connecting to controller. first time i get data and the SDA line goes low. then again after connecting encoder to usb interface and reconnecting to controller, it gives only one data and again SDA line goes low.

    if SDA line goes low and I debug again without connecting it to  UPRGAM4096 (which also has its own software) and reconnecting to controller, it does not give data one time also.
    the problem is that i have to connect the am4096 with UPRGAM4096 and again to controller everytime. still i get only 1 time data and the SDA goes low.
    i am attaching my updated code (only while loop because i have not change anything in initialization and it is mentioned in previous msg).
    while(1)
    {
        while (I2C_isBusBusy(myI2C0_BASE));  // Ensure bus is not busy
    
        // Write operation
    
        I2C_setConfig(myI2C0_BASE, I2C_MASTER_SEND_MODE | I2C_REPEAT_MODE);
        I2C_setSlaveAddress(myI2C0_BASE, 90);  // 90 addr
        DEVICE_DELAY_US(30);
        I2C_setDataCount(myI2C0_BASE, 1);
        DEVICE_DELAY_US(30);
        I2C_putData(myI2C0_BASE, 0x20);  // Command/Register to read from
        DEVICE_DELAY_US(30);
        I2C_sendStartCondition(myI2C0_BASE);
        DEVICE_DELAY_US(30);
        while (!(I2C_getStatus(myI2C0_BASE) & I2C_STS_REG_ACCESS_RDY));
        DEVICE_DELAY_US(30);
    //        DEVICE_DELAY_US(500);
    
        // Read operation
        I2C_setConfig(myI2C0_BASE, I2C_MASTER_RECEIVE_MODE | I2C_REPEAT_MODE);
        DEVICE_DELAY_US(30);
        I2C_setSlaveAddress(myI2C0_BASE, 90);
        DEVICE_DELAY_US(30);
        I2C_setDataCount(myI2C0_BASE, 2);  // Assuming you want to read 2 bytes
        DEVICE_DELAY_US(30);
        I2C_sendStartCondition(myI2C0_BASE);  // Repeated start for read operation
        DEVICE_DELAY_US(30);
    
        // Wait for data to be ready and read it
        for (i = 0; i < 2; i++) {
            while (!(I2C_getStatus(myI2C0_BASE) & I2C_STS_REG_ACCESS_RDY));
            I2C_buf[i] = I2C_getData(myI2C0_BASE);
            DEVICE_DELAY_US(30);
        }
    
        I2C_sendStopCondition(myI2C0_BASE);  // Stop condition
        DEVICE_DELAY_US(30);
    }
    thanks and regards 
    Muzammil Qureshi
  • Hello Muzammil,

    Please provide a screenshot of the communication taking place and where the issue occurs. Can you also tell me what the values of the pullup resistors are on SDA/SCL?

  • Hello Omer,

    Please provide a screenshot of the communication taking place and where the issue occurs.

    i get data first time. After the arrow marked by me, the SCL line always goes low. then I debug my project again and i see this.

     now, my SDA line goes low. this process occurs until i connect it ot UPRGAM4096 interface and reconnect to controller again.

    i am attaching the screenshot of usb software interface.

    Can you also tell me what the values of the pullup resistors are on SDA/SCL?

    I am using RMK4 eval board. here is the schematic.

    I have set my pins as 'Open-drain output with pull-up enabled output and input' by sysconfig. 

    i have already given my lots of time for I2C of my project, please help me with this.

    thanks and regards

    Muzammil Qureshi.

  • Hello Muzammil,

    In the second screenshot, could you check the I2CSTR to see if there is a NACK or any other status bits are set besides the bus busy bit?

    i am attaching the screenshot of usb software interface.

    I'm confused by your mention of the USB setup for the interface you're connecting to, is the I2C lines and USB lines shared in some way for the communication? You mentioned before: "I am getting the data only one time and that also after connecting AM4096 encoder to its own USB hardware (UPRGAM4096) and then again connecting to controller.", but this doesn't entirely make sense to me based on the attached schematic. The I2C and USB hardware connections should be independent.

    If you are able to, one way you can verify whether the F2837xS I2C peripheral is functioning properly is running the external loopback example from C2000Ware; this will verify whether there is something occurring on the F2837xS side or the target device's side. Let me know if you're able to run this example without issues using the pins you're trying to use for this project.