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.

LAUNCHXL-F28379D: I2C "Send Start Condtion" bit STT does not come back to zero. Thus causing program to stuck at one point.

Part Number: LAUNCHXL-F28379D


I am using an I2C example "i2c_ex4_eeprom_polling.c". At the very start of the code when the program checks for connected I2C devices it executes the following code. The "I2CBusScan", GPIO initialization, and I2C initialization are also shown. The problem I am facing is when the code reaches I2C_sendStartCondition(base); in function I2CBusScan()It sets the STT bit (shown in the attached image) high. According to the datasheet SPRUHM81 page 2331, the STT bit should come back to Zero after the I2C_sendStartCondition(base); command. However, in my case, it stays at one. When I stay at one then the condition while(!(I2C_getStatus(base) & I2C_STS_REG_ACCESS_RDY)); becomes true and the loop continues for infinite time. 

Sometimes it works. But most of the time it will stick at this line. Also, sometimes when I unplug and replug LAUNCHXL-F28379D it starts working again for some time and then stops working again. I don't understand what is the problem. I am using a sensor from Analog Devices ADXL345.

Thank you

// Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize I2C pins
    //
    I2C_GPIO_init();

    //
    // Initialize PIE and clear PIE registers. Disable CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    I2Cinit();
    //SerialBegin(9600);
    //I2Cs connected to I2CA will be found in AvailableI2C_slaves buffer
    //after you run I2CBusScan function.
    uint16_t *pAvailableI2C_slaves = AvailableI2C_slaves;
    status = I2CBusScan(I2CA_BASE, pAvailableI2C_slaves);

uint16_t I2CBusScan(uint32_t base, uint16_t *pAvailableI2C_slaves)
{
    uint16_t probeSlaveAddress, i;

    //Disable interrupts on Stop condition, NACK and arbitration lost condition
    I2C_disableInterrupt(base, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));

    i = 0;
    for(probeSlaveAddress=1;probeSlaveAddress<=MAX_10_BIT_ADDRESS;probeSlaveAddress++)
    {
        //Check I2C bus status
        status = checkBusStatus(base);
        if(status)
        {
           ESTOP0;
           return status;
        }

        I2C_setConfig(base, (I2C_MASTER_SEND_MODE | I2C_REPEAT_MODE));

        //Enable 10-bit addressing if probeSlaveAddress is greater than 127U
        if(probeSlaveAddress > MAX_7_BIT_ADDRESS)
        {
            //10-bit addressing
            I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS);
        }

        // Setup slave address
        I2C_setSlaveAddress(base, probeSlaveAddress);

        I2C_sendStartCondition(base);


        uint16_t stts = I2C_getStatus(base);
        //Wait for the slave address to be transmitted
        while(!(I2C_getStatus(base) & I2C_STS_REG_ACCESS_RDY));

        //Generate STOP condition
        I2C_sendStopCondition(base);

        //Wait for the I2CMDR.STP to be cleared
        while(I2C_getStopConditionStatus(base));

        //Wait for the Bus busy bit to be cleared
        while(I2C_isBusBusy(base));

        uint16_t I2CStatus = I2C_getStatus(base);

        //If Slave address is acknowledged, store slave address
        //in pAvailableI2C_slaves
        if(!(I2CStatus & I2C_STS_NO_ACK))
        {
            pAvailableI2C_slaves[i++] = probeSlaveAddress;
        }
        //Clear NACK bit in I2CSTR
        I2C_clearStatus(base,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
    }

    I2C_setConfig(base, (I2C_MASTER_SEND_MODE));
    I2C_setAddressMode(base, I2C_ADDR_MODE_7BITS); //7-bit addressing
    I2C_enableInterrupt(base, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
    return SUCCESS;
}


void I2C_GPIO_init(void)
{
    // I2CA pins (SDAA / SCLA)
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SDAA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAA, GPIO_PIN_TYPE_PULLUP);
    GPIO_setMasterCore(DEVICE_GPIO_PIN_SDAA, GPIO_CORE_CPU1);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAA, GPIO_QUAL_ASYNC);

    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCLA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLA, GPIO_PIN_TYPE_PULLUP);
    GPIO_setMasterCore(DEVICE_GPIO_PIN_SCLA, GPIO_CORE_CPU1);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLA, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAA);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLA);
}

void I2Cinit(void)
{
    //myI2CA initialization
    I2C_disableModule(I2CA_BASE);
    I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_33);
    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
    //I2C_setSlaveAddress(I2CA_BASE, 80);
    //I2C_setOwnSlaveAddress(I2CA_BASE, 96); //I2CA address
    I2C_disableLoopback(I2CA_BASE);
    I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
    //I2C_setDataCount(I2CA_BASE, 2);
    I2C_setAddressMode(I2CA_BASE, I2C_ADDR_MODE_7BITS);
    I2C_enableFIFO(I2CA_BASE);
    I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
    I2C_setFIFOInterruptLevel(I2CA_BASE, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);
    I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
    I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
    I2C_enableModule(I2CA_BASE);
}

void initializeBuff(void)
{
    uint16_t i;
    for(i=0;i<MAX_BUFFER_SIZE;i++)
    {
        TX_MsgBuffer[i] = 0;
        RX_MsgBuffer[i] = 0;
    }
}

  • Hi Syed,

    It will help to look at the I2CSTR bit values when this issue occurs to better understand what's happening. Also probing the I2C signals with an analyzer or oscilloscope to see the bus activity.

    Maybe the START condition is never getting generated for some reason.

    Best,

    Kevin

  • Syed,

    In your above code snippet, you have commented out below lines as shown below. You need to configure slave address you are talking to and configure I2C own slave address. You can't initiate I2C communication without writing to these registers.

    I2C slave address ADXL345 should be written into I2CSAR register

    //I2C_setSlaveAddress(I2CA_BASE, 80);       

    I2CA should have its own slave address

    //I2C_setOwnSlaveAddress(I2CA_BASE, 96); //I2CA address

    Regards,

    Manoj

  • Yes I have commented these lines. As for the Slave address of peripherals I write this line when I am initiating communication with a specific sensor. I.e reading or writing

    For own slave Address I thought I don't need it if I don't want to use my MCU in slave mode. 

  • I have narrowed down problem. When I debug and run the program. If it doesn't work then I disconnect the sensor (plug out +3V wire) and stop the debugging. The next time if I start debugging it will work for sure. 

    If I understand it correctly if I stop debugging somewhere in the while loop( reading data) the I2C device connected will stuck ( sometimes ). Untill you turn off and turn on it will not work. 

    If I load the program permanently then everytime i turn on MCU with I2C connected already i will work. My problem you can say is kind of solved. But I still don't know why during debugging, if I stop it, it hangs some where until i disconnect sensor and reconnect it.

  • But I still don't know why during debugging, if I stop it, it hangs some where until i disconnect sensor and reconnect it.

    That might be due to External Slave Device Hanging the Bus by Holding SDA Low

  • Yes, exactly this was the problem.