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.

AM2632: AM2632 IIC

Part Number: AM2632
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hi TI Support Team,

I am encountering an issue with the I2C communication between the AM2632 and a humidity/temperature sensor(NSHT30-Q1DNR). I would appreciate your guidance to resolve this problem.

Problem:

  • Write works, but read fails: After sending the slave address (with R/W=1), the sensor ACKs, but SCL stays LOW.

  • I have tried various read and write operations, and each read operation has the same response, so I cannot output clk completely

  • I am certain that slave is functioning normally

Setup:

  • Sensor:  at 7-bit address 0x44.

  • I2C speed: 400 kHz (standard mode).

  • Pull-ups: 4.7kΩ on SDA/SCL.

Question:
Why would SCL stay low after a slave ACK during a read? Could this be a master configuration issue or sensor behavior?

Attachments:

  • Logic analyzer capture (SCL_stuck.png).

Thanks for your help!

Best regards,

zx

  • Hi ZX, 

    If you slow down the bit rate to 100kbps, are you able to read?

    Regards,

    Brennan

  • Hi Brennan:

    I have tried 100K, but it still shows the same phenomenon. The slave supports up to 1M clock speed

    Best regards

    zx

  • Hi ZX,

    Your sysconfig and hardware configurations look correct. I am adding a software expert to this thread for further investigation.

    It would help if you can provide some details about your code. 

    Regards,

    Brennan

  • Hi  Brennan:

    Here is my code,I made some modifications to the routine example of sdk

    /*
     *  Copyright (C) 2024 Texas Instruments Incorporated
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <drivers/i2c.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    
    extern uint32_t Board_i2cGetEepromDeviceAddr(void);
    #define I2C_READ_LEN                    (6U)
    
    static void i2c_read_error_handler(uint16_t sample, int32_t status);
    
    void i2c_read_main(void *arg0)
    {
        uint16_t        sample;
        int32_t         status;
        uint32_t        i2cReadTargetAddr;
        uint8_t         rxBuffer[I2C_READ_LEN];
        uint8_t         txBuffer[2];
        I2C_Handle      i2cHandle;
        I2C_Transaction i2cTransaction;
    
        Drivers_open();
        Board_driversOpen();
    
        i2cReadTargetAddr     = 0x44;//Board_i2cGetEepromDeviceAddr();
        i2cHandle = gI2cHandle[CONFIG_I2C0];
    
        DebugP_log("[I2C] Read data ... !!!\r\n");
    
        /* Set default transaction parameters */
        I2C_Transaction_init(&i2cTransaction);
        i2cTransaction.writeBuf      = txBuffer;
        i2cTransaction.readBuf      = rxBuffer;
        i2cTransaction.writeCount    = 2;
        i2cTransaction.readCount    = 1;
        i2cTransaction.targetAddress = i2cReadTargetAddr;
        txBuffer[0] = 0x24;
        txBuffer[1] = 0x16;
    
        status = I2C_transfer(i2cHandle, &i2cTransaction);
    
        I2C_Transaction_init(&i2cTransaction);
        /* Override with required transaction parameters */
        i2cTransaction.readBuf      = rxBuffer;
        i2cTransaction.readCount    = I2C_READ_LEN;
        i2cTransaction.targetAddress = i2cReadTargetAddr;
    
        /* Read 20 samples and log them */
        // for(sample = 0; sample < 20; sample++)
        // {
            status = I2C_transfer(i2cHandle, &i2cTransaction);
            if(status == I2C_STS_SUCCESS)
            {
                DebugP_log("[I2C] Sample %u: %u\r\n", sample, rxBuffer[0]);
            }
            else
            {
                i2c_read_error_handler(sample, i2cTransaction.status);
            }
        // }
    
        DebugP_log("[I2C] Read data ... DONE !!!\r\n");
        if(status == SystemP_SUCCESS)
        {
            DebugP_log("All tests have passed!!\r\n");
        }
        else
        {
            DebugP_log("Some tests have failed!!\r\n");
        }
    
        Board_driversClose();
        Drivers_close();
    
        return;
    }
    
    static void i2c_read_error_handler(uint16_t sample, int32_t status)
    {
        switch(status)
        {
            case I2C_STS_ERR:
                DebugP_logError("[I2C] Sample %u: Generic error occurred", sample);
                break;
            case I2C_STS_ERR_TIMEOUT:
                DebugP_logError("[I2C] Sample %u: Timeout error occurred", sample);
                break;
            case I2C_STS_ERR_NO_ACK:
                DebugP_logError("[I2C] Sample %u: No acknowledgement received", sample);
                break;
            case I2C_STS_ERR_ARBITRATION_LOST:
                DebugP_logError("[I2C] Sample %u: Arbitration lost", sample);
                break;
            case I2C_STS_ERR_BUS_BUSY:
                DebugP_logError("[I2C] Sample %u: Bus Bus Busy error occurred", sample);
                break;
        }
    
        return;
    }

    Looking forward to your reply

    zx

  • Hi ZX,

    From my initial analysis I have a few points:

    1. In your code, I see that after the I2C Write operation, you call the "I2C_Transaction_init()" function and populate 3 parameters (Targer address, readBufa nd ReadCount). The other parameters such as Timeout, Controller mode, status and other args take default values as shown below

    Make sure the I2C Transaction structure is configured correctly before you call the Read operations

    2. I understand why the I2C_READ_LEN was changed to "6", but according to the datasheet of the sensor, master should send ACK after each of the first 5B are received and STOP command after the 6th Byte. Can you verify if this is happening? The Logic analyzer capture is not opening in a high resolution for me so I could not look closely.

    3. I see no issues in the code, I believe we are missing some step in terms of performing read operation correctly. 

    Regards,
    Shaunak

  • Hi Shaunak:

    Thanks for you reply.

    1. I referred to multiple routines, which only configured the Targer address, readBufa nd ReadCount, I followed his instructions, and I have also configured Timeout before, but I did not read the data properly. Is it better to use the default parameters for other parameters

    2. The current problem is that when reading, after sending the slave address, the clk terminates and becomes low

    Regards 

    zx

  • Hi ZX,

    I believe the issue is with I2C address. Do not set the own slave address same as any other slave on the bus, the purpose of own slave address is for slave mode operation of the Controller, keep it default or at least different from any other slave in the bus otherwise the IP will lock up

    Regards,
    Shaunak

  • Hi Shaunak:

    There is only one slave on my IIC bus。

    I want to know if this phenomenon is caused by the host actively pulling down,and why

    Thanks

    ZX

  • Hi ZX,

    Even if there is only one slave on the I2C bus, the own slave address of am263x must be different from the slave's address connected. The AM263x slave address should only be used when AM263x is in slave mode.

    I want to know if this phenomenon is caused by the host actively pulling down,and why

    Yes this can be the case, but before jumping there, I just want to once confirm if changing the address fixes this.

    Regards,
    Shaunak

  • Hi Shaunak:

      Sorry, I misunderstood. I mistakenly configured 'Own Target Address' as slave address.

      I have corrected the configuration and will conduct thorough testing to verify the functionality. I will promptly share the test results with you once completed.

    Thank you again for your patience and support

    zx

  • Hi Shaunak:

    I fixed this by changing the address.

    Thanks for your help

    zx