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.

TM4C1294NCPDT: I2C Multiple Data Byte Transfer: Bytes being skipped

Part Number: TM4C1294NCPDT

I'm using the I2C1 peripheral with an AT24CM01 EEProm.  I'm attempting to write some dummy values into the EEProm to see if I can write and read the data out properly.  The code below writes the Address of the device followed by a 2 byte memory address followed by 50 Data Bytes.  The value of the Data bytes increments from 0 to 49.

The issue I'm having is missing data bytes.  For instance, when I watch the transmission on an oscilloscope, the Data byte should increment from 0 to 49 but when it runs, data bytes are being skipped.  (i.e.  1 --> 3 -->6-->9 etc instead of 0-->1-->2-->3)

If I insert Breakpoints in the code(as highlighted below) each byte is written correctly and the code works correctly.  When the Breakpoints are removed, data bytes are skipped.  The BUSY bit in the I2CMCS register doesn't seem to ever get set to "1" as the data is being clocked out.  I've included the relevant code snippets I'm using to setup the I2C1 peripheral along with the simple test code.

Have I missed a setup step?

Thanks,

Joe

#define EXTERNAL_MEM_PERIPH          I2C1_BASE

void main(void)
{
       //-- Setup the I2C Port --
    TD_Init_I2CPorts(dwSystemClock);    //dwSystemClock = 120MHz

    ExternalMem_Init(EXTERNAL_MEM_PERIPH);
}

//  Initialization routine
static void TD_Init_I2CPorts(uint32_t dwSystemClock)
{

    //-- Enable I2C1
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
    while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1))
    {
    }

    //-- Enable Port G pins for I2C1
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);


    //-- Configure G0 and G1 for I2C
    ROM_GPIOPinConfigure(GPIO_PG0_I2C1SCL);
    ROM_GPIOPinConfigure(GPIO_PG1_I2C1SDA);

    ROM_GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);
    ROM_GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);

    //Setup the transfer speed for 400kbps and run off of the System Clock
    I2CMasterInitExpClk(I2C1_BASE, dwSystemClock, true);

}

//Dummy Variable Write operation
uint32_t ExternalMem_Init(uint32_t dwCommPort)
{
    uint32_t  dwNumberofBytes =  50;
    uint32_t  i;
    volatile uint32_t  dwSlaveAdd;
    uint32_t   byLowerAddress = 0x0A;
    volatile uint32_t   byData = 0;
    volatile uint32_t   counter = 0;
    volatile uint32_t  dwReturnedData[50];
    volatile uint32_t  dwError = 0x000;


    dwSlaveAdd = EXT_MEM_SLAVE_ADDRESS | EXT_MEM_WRITE | EXT_MEM_LOWER_PAGES;

    I2CSlaveAddressSet(EXTERNAL_MEM_PERIPH,0,dwSlaveAdd);

    //-- Send the Slave Address and Upper Address
    HWREG(EXTERNAL_MEM_PERIPH + I2C_O_MSA) = dwSlaveAdd;
    I2CMasterDataPut(EXTERNAL_MEM_PERIPH,0x00);
    while(I2CMasterBusBusy(EXTERNAL_MEM_PERIPH))
       {
        }

    I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_START);
    while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
       {
       }

    //-- Send the lower byte of the Memory Address
    I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byLowerAddress);     // BREAK POINT HERE
    I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_CONT);

    while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
       {
       }


    //Write Data
    for(i=0; i < dwNumberofBytes; i++)
       {
        I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byData);       //BREAK POINT HERE

        if((i+1) == dwNumberofBytes)
           {
           I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_FINISH);
           }
        else
           {
           I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_CONT);
           }
        //-- Wait for Master to finish
        while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
           {
           }


        byData++;

       }

  • Hi Joe,

     Can you try

    Replacing:

       I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_START);

       while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))

          {

          }

       //-- Send the lower byte of the Memory Address

       I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byLowerAddress);     // BREAK POINT HERE

    With:

       I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_START);

     while(!I2CMasterBusy(EXTERNAL_MEM_PERIPH)) // Add this code

          {

          }

       while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))

          {

          }

       //-- Send the lower byte of the Memory Address

       I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byLowerAddress);     // BREAK POINT HERE

    You might want to try the same for the second place highlighted in yellow in your code.

  • Hi Charles,

    That did it.  I tried adding a small delay but evidently it wasn't long enough.  Thanks for the advice.

    Joe