Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Problem trying to send several bytes using I2C, TM4C123 biard

Status
Not open for further replies.

JavierMA

New Member
Hi all,

I am asking for your help because I am trying to send several bytes using the I2C protocol in a program wich makes use of 2 I2C modules, and looks that it gets stuck after sending the first byte when checking the BUSY bit in I2CMCS. The board I am programming is the TM4C123GH6PM.
Here is the block diagram:
Screenshot 2020-08-07 at 20.51.02.png


And here is the diagram available in the board's Data Sheet:

Screenshot 2020-08-07 at 20.38.35.png


And this is the code in charge of sending the array content:

C:
int touch_lcd_write(enum typeOfWrite type, char command_data[], short I2C, int len)

{

            //Some code not related with the problem


            i=0;

            while(I2C1_MCS_R&I2C_MCS_BUSBSY);

            I2C1_MSA_R =write_touch_addr; //Specify the slave address of the master and that the next operation is a Transmit

            I2C1_MDR_R=command_data;    // Register address

            I2C1_MCS_R=0x03;    // (START, RUN).

            while(I2C1_MCS_R&I2C_MCS_BUSY != 0); //here gets stucked

            //Check if an error happens

            if(I2C1_MCS_R&I2C_MCS_ERROR)    //Check the ERROR bit in the I2CMCS register to confirm the transmit was acknowledged.

            {

                //Send stop

                I2C1_MCS_R=0x04;

                if(I2C1_MCS_R&I2C_MCS_ARBLST)

                {

                    return 1;

                }

                else

                {

                    return 2;

                }

            }

            i++;

            while(i<len)

            {

                I2C1_MDR_R=command_data;    // Register address

                if(i==len-1)

                {

                    //Last byte. Generate RUN and STOP

                    I2C1_MCS_R=0x05; //RUN,STOP

                }

                else

                {

                    //Generate RUN as it is not the last byte

                    I2C1_MCS_R=0x01; //RUN

                }

                while(I2C1_MCS_R&I2C_MCS_BUSY != 0);   //Wait until the transmiI2Con completes by polling the I2CMCS register's BUSBstart_Y bit until it has been cleared.

                if(I2C1_MCS_R&I2C_MCS_ERROR)    //Check the ERROR bit in the I2CMCS register to confirm the transmit was acknowledged.

                {

                    if(I2C1_MCS_R&I2C_MCS_ERROR)    //Check the ERROR bit in the I2CMCS register to confirm the transmit was acknowledged.

                    {

                        //Send stop

                        I2C1_MCS_R=0x04;

                        if(I2C1_MCS_R&I2C_MCS_ARBLST)

                        {

                            return 1;

                        }

                        else

                        {

                            return 2;

                        }

                    }

                }

                i++;

            }

}

If I am not wrong, I am correctly following the diagram, but I can't see what is going wrong, so any help is appreciated.

Thanks,
Javier
 
Hi Mike,

Thanks for asking, that reminds me I forgot to add that information to my first post. About your question, I can tell that the lines for both I2C connections have pullup resistors with the correct values as they came integrated with the touch display I bought.


Regards,
Javier
 
Last edited:
Assuming all the hardware is correct then I would suggest using a different master/slave to see at which end the problem is. Do you have something that you can use as a know good master? Even an Arduino will do. Also, the I2C bus can become unresponsive if a transmission is interrupted which can happen when a ner compile is initiated.

Mike.
 
Yes, I can use an Arduino Uno. Anyway, I just found the error and it is kind of funny. I have the I2C device connected through prototype cables and a very small PCB with a ZIF to SMD connector and by chance I pressed a cable end and it just started to work.

Here is the code with the comments edited just in case anyone reading it is interested:

C:
int touch_lcd_write(enum typeOfWrite type, char command_data[], short I2C, int len)
{
            //Some code not related with the problem

            i=0;
            while(I2C1_MCS_R&I2C_MCS_IDLE != 0x20);
            I2C1_MSA_R =write_touch_addr; //Specify the slave address of the master and that the next operation is a Transmit
            I2C1_MDR_R=command_data;    // Register address
            while(I2C1_MCS_R&I2C_MCS_BUSBSY);
            I2C1_MCS_R=0x03;    // (START, RUN).
            while(I2C1_MCS_R&I2C_MCS_BUSY != 0);
            //Check if an error happens
            if(I2C1_MCS_R&I2C_MCS_ERROR)    //Check the ERROR bit in the I2CMCS register to confirm the transmit was acknowledged.
            {
                I2C1_MCS_R=0x04;   //Send STOP
                if(I2C1_MCS_R&I2C_MCS_ARBLST)
                {
                    return 1;
                }
                else
                {
                    return 2;
                }
            }
            i++;
            while(i<len)
            {
                I2C1_MDR_R=command_data;    // Register address
                if(i==len-1)
                {
                    //Last byte. Generate RUN and STOP
                    I2C1_MCS_R=0x05; //RUN,STOP
                }
                else
                {
                    //Generate RUN as it is not the last byte to be sent
                    I2C1_MCS_R=0x01;
                }
                while(I2C1_MCS_R&I2C_MCS_BUSY != 0);   //Wait until the transmission completes by polling the I2CMCS register's BUSY bit.
                if(I2C1_MCS_R&I2C_MCS_ERROR)    //Check the ERROR bit in the I2CMCS register to confirm the transmit was acknowledged.
                {
                    I2C1_MCS_R=0x04; //Send STOP
                    if(I2C1_MCS_R&I2C_MCS_ARBLST)
                    {
                        return 1;
                    }
                    else
                    {
                        return 2;
                    }
                }
                i++;
            }
}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top