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.

Problem in reading temperature sensor TMP101 using I2C with TM4C123FH6PM

Other Parts Discussed in Thread: TMP101, TM4C123FH6PM

Hi,

I'm trying to read TMP101 using I2C1 of TM4C123FH6PM. But i'm always getting '0' value. Following is my code.

//uart initialization

void uart_init(void)
{
    //
    // Initialize the UART.
    //
     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
     ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
     ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
     ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
     UARTStdioInit(0);

     UARTprintf("Hello, world!\n");
}

// i2c init

void i2c_init(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    GPIOPinConfigure(GPIO_PA6_I2C1SCL);

    GPIOPinConfigure(GPIO_PA7_I2C1SDA);

    GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    HWREG(I2C1_MASTER_BASE + I2C_O_MCR) |= 0x01;


    I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);

    I2CSlaveEnable(I2C1_SLAVE_BASE);

    I2CSlaveInit(I2C1_SLAVE_BASE, SLAVE_ADDRESS);

    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, false);

}

main(void)
{
    unsigned long i;
    unsigned long ulRecData;
    unsigned long ulMasterData[2] = {0x00, 0xAA};

    FPUEnable();
    FPULazyStackingEnable();

 
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                           SYSCTL_XTAL_16MHZ);
    uart_init();
    i2c_init();



    I2CMasterDataPut(I2C1_MASTER_BASE, ulMasterData[0]);

    I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);

//    while(I2CMasterBusBusy(I2C_MASTER_BASE))
    {
    }

    I2CMasterDataPut(I2C1_MASTER_BASE, ulMasterData[1]);

    I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);


//    while(I2CMasterBusBusy(I2C_MASTER_BASE))
    {
    }

   /* Read the data */

    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, true);


    I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);


//    while(I2CMasterBusBusy(I2C_MASTER_BASE))
    {
    }


    ulRecData = I2CMasterDataGet(I2C1_MASTER_BASE);

    UARTprintf(" Data Received: %4d\n", ulRecData);




   while(1)
    {
        for(i=0;i<60000;i++)
        {
            if(i==59999)
            {
                I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);

                ulRecData = I2CMasterDataGet(I2C1_MASTER_BASE);

                UARTprintf(" Data Received: %4d\n", ulRecData);
            }
        }
    }

}

Also, if i use 

while(I2CMasterBusBusy(I2C_MASTER_BASE)) {}

the code is getting stuck there.

Any solution for this.

Any help is much appreciated

-Bijo

  • Hi Bijo,

     

    Bijo Mathew said:
    //    while(I2CMasterBusBusy(I2C_MASTER_BASE))
        {
        }
      

    Do you really intend to comment out the while(), or is it just some random mistake?

    -kel


  • Hi Kel,

    I've mentioned it in bottom side of my first post.

    If i use that while(), the code is getting stuck there. That is why i commented it.

    -Bijo

  • Hi Kel,

    I've made some more changes. But, still it is not working. Changes are following.

    unsigned long ulMasterData[3] = {0x9A, 0x00, 0x9B};

        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, false);

        I2CMasterDataPut(I2C1_MASTER_BASE, ulMasterData[0]);

        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //    while(I2CMasterBusBusy(I2C_MASTER_BASE))
        {
        }

        I2CMasterDataPut(I2C1_MASTER_BASE, ulMasterData[1]);

        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);


    //    while(I2CMasterBusBusy(I2C_MASTER_BASE))
        {
        }


        I2CMasterDataPut(I2C1_MASTER_BASE, ulMasterData[2]);

        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);


    //    while(I2CMasterBusBusy(I2C_MASTER_BASE))
        {
        }

       /* Read the data */

        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, true);


        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);


    //    while(I2CMasterBusBusy(I2C_MASTER_BASE))
        {
        }

        ulRecData = I2CMasterDataGet(I2C1_MASTER_BASE);

        UARTprintf(" Data Received: %4d\n", ulRecData);



        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);


    //    while(I2CMasterBusBusy(I2C_MASTER_BASE))
        {
        }

        ulRecData = I2CMasterDataGet(I2C1_MASTER_BASE);

        UARTprintf(" Data Received: %4d\n", ulRecData);

        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, true);


        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);


    //    while(I2CMasterBusBusy(I2C_MASTER_BASE))
        {
        }

        ulRecData = I2CMasterDataGet(I2C1_MASTER_BASE);

        UARTprintf(" Data Received: %4d\n", ulRecData);

    I'm trying as mentioned in TMP101datasheet. Bt every time value read is 0(zero) only.

    -Bijo

  • Hi Bijo,

        It's break time where I am. So, I did not look into more details of your code. I will get back to you. However I spot this below from your code. 

    Bijo Mathew said:
     HWREG(I2C1_MASTER_BASE + I2C_O_MCR) |= 0x01;

    This line sets the I2C in loopback mode, if I am not wrong.

    Also, see this post below. Take note of the use of GPIOPinTypeI2CSCL() for the I2C SCL pin

    I2C Setup problem

    -kel


  • Hi Kel,

    I've removed the loopback mode function and added GPIOPinTypeI2CSCL(). Still the program is not working. It is getting stuck at I2CMasterBusy(I2C1_MASTER_BASE) function.

    My program...

    i2c_init(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

        SysCtlPeripheralEnable( I2C1_MASTER_BASE );

        I2CMasterEnable(I2C1_MASTER_BASE);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

        GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);

        GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);

        GPIOPinConfigure(GPIO_PA6_I2C1SCL);

        GPIOPinConfigure(GPIO_PA7_I2C1SDA);

        I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);

        I2CSlaveEnable(I2C1_SLAVE_BASE);

        I2CSlaveInit(I2C1_SLAVE_BASE, SLAVE_ADDRESS);
    }

    temp_i2cread(void)
    {
        unsigned long ulRecData;

        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS >> 1, false);

        I2CMasterDataPut(I2C1_MASTER_BASE, 0x00); 

        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START); 

        while(I2CMasterBusy(I2C1_MASTER_BASE))
         {
         }

        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS >> 1, true);      

        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

        while(I2CMasterBusy(I2C1_MASTER_BASE))
         {
         }

        ulRecData = ROM_I2CMasterDataGet(I2C1_MASTER_BASE);

        UARTprintf(" Data Received: %4d\n", ulRecData);
    }

    -Bijo

  • Hi Bijo,

        My limited experience with the use of I2C, also limits my expert advice. Better, wait for others to reply. However, I spot these lines of code below that seems not right. I used the I2C example code and drivers library user guide as reference. 

    Bijo Mathew said:
    SysCtlPeripheralEnable( I2C1_MASTER_BASE );

    I think this should be

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

    Bijo Mathew said:
    I2CMasterEnable(I2C1_MASTER_BASE)

    This line is already called inside I2CMasterInitExpClk()

    Also, search this forum regarding I2C.

    -kel

  • Are physical pull-up R's - both I2C lines - present/accounted for?

  • HI cb1,

    Both pull ups are given- 4.7k.

    I've gone through so many posts, your posts also. I've made so many changes in my code still not working.

    My code....

    void i2c_init(void)
    {

        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

        GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
        GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);

        GPIOPinConfigure(GPIO_PA6_I2C1SCL);
        GPIOPinConfigure(GPIO_PA7_I2C1SDA);

        I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);
        SysCtlDelay(10000);

    }


    void temp_i2cread(void)
    {
        unsigned long ulRecData;


        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, false);

        // Write SUB to data register.
        I2CMasterDataPut(I2C1_MASTER_BASE, 0x00);

        // Send a start condition, slave address and first byte.
        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);

        // Loop until transfer complete.
        while(I2CMasterBusy(I2C1_MASTER_BASE))
        {
        }

        // Set slave address with receive operation.
        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, true);

        // Send address again with repeated start condition.
        I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

        // Loop until transfer complete.
        while(I2CMasterBusy(I2C1_MASTER_BASE)){}

        // Read data.
        ulRecData = I2CMasterDataGet(I2C1_MASTER_BASE);

        UARTprintf("Data Received: %4d\n", ulRecData);


    }

    -Bijo

  • @ Bijo,

    Stunned by the appeal/cleverness of your post, Bijo.  (you "sold" me - that selling so often over-looked - this expanse)

    Pardon - but haven't the time now to fully/properly review your code.  (my own cascade of code cries out)

    Have you access to a scope? 

    Can you confirm that you have data toggling - both SDA & SCL.  (should approach 0V and 3V3 - each line - if no 3V3 then measure those pull-ups) 

    Is your Slave properly powered - and not prior to - or after - the MCU receives/loses power?

    Do you really/fully understand the Slave Address handling?  (it is a 7 bit address - w/ read/write automatically handled by the Stellaris function)  Post the Slave's data sheet's mention of the slave address - so that others may check.  If wrong - all further efforts prove futile.

    Have you "ohmed-out" SDA & SCL - from MCU pins to Slave? 

    Can you beg/borrow/steal (or God forbid) buy a cheap/dirty I2C based EEProm - simplest possible - so that you "ease" your initial I2C attempt?

    Always hardest when "starting" - virtually anything can be "wrong" - and plague!  You need to systematically confirm (some modeling here - I hope) - that your "basics" are covered.

    Wish you well...

     

  • Hi cb1,

    My code is getting stuck at first while(I2CMasterBusy(I2C1_MASTER_BASE)){} itself. Pull up  resistors and bypass capacitor are connected.

    So, can i assure that the problem is with the temp sensor or its address...???

  • Hi cb1,

    I've tested with scope.

    Initially, because of the pull ups both SCL and SDA are pulled up. After i2c_init() function also both are pulled up. Then, in temp_i2cread() function upto I2CMasterDataPut(), both are pulled up. When I2CMasterControl() function is called both SCL and SDA goes pulled down. Then, code will get stuck in the next line, ie,

    while(I2CMasterBusy(I2C1_MASTER_BASE)){}

    What should i do to overcome this....???

    -Bijo

  • Given that this is ages ago, I'm guessing you came up with a solution one way or another by now...if not, try replacing your while loop to the two loops below, in case the TM4C123 suffers from the same issue as the TM4C129.  That issue is that the clock speed is so fast, that the original single while loop gets skipped over before the I2C even happens.

    while(!I2CMasterBusy(I2C2_BASE));   

    while(I2CMasterBusy(I2C2_BASE));