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.

TMS320F28379D: I2C without interrupts regarding the FIFO

Part Number: TMS320F28379D


Tool/software:

Hi all,

I have a query regarding the driverlib functions call regarding I2C example.

I need to send 27 bytes to the SSD1306 display device for initializing it via I2C.

When I try to send only the first 16 characters to the I2C slave, i get the required data on the I2C bus. I verified it using the logic analyser :

first 16 bytes, i2c

When I try to send the 27 characters in two batches, 16+11, I get only the last 16 bytes in the I2C bus, 5 from the first batch and 11 from the second batch. Logic analyser output:

I have pasted the relevant i2c function code below.

It would be helpful if some one can point out what I am doing wrong : 

void init_i2c_module()

{
// https://software-dl.ti.com/C2000/docs/C2000_driverlib_api_guide/f2837xd/html/modules/i2c.html#
I2C_disableModule(I2CA_BASE);//Before initializing the I2C module, the user first must put the module into the reset state
I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 10000, I2C_DUTYCYCLE_50);//the user must then call I2C_initMaster() which will configure the rate and duty cycle of the master clock.
I2C_setDataCount(I2CA_BASE, 16);// Set data count must be before enable fifo
I2C_enableFIFO(I2CA_BASE);
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);//I2C_setConfig() should be called to configure the behavior of the module
I2C_setSlaveAddress(I2CA_BASE, 0x3C);
I2C_enableModule(I2CA_BASE);

I2C_putData(I2CA_BASE,0x00);// First byte: Command identifier 0x00 is the first byte, remaining 15 bytes are put in the FIFO using for loop below
for (iter=0;iter<=14;iter++)// Remaining 15 bytes of the init data to fill up the FIFO
{
     I2C_putData(I2CA_BASE,s_oled128x64_initData[iter]);
}
I2C_sendStartCondition(I2CA_BASE);
I2C_sendStopCondition(I2CA_BASE);

// Of the total 27 bytes, 16 sent earlier, 11 more are pending.
I2C_setDataCount(I2CA_BASE, 11);
for (iter=15;iter<=24;iter++)// 10 bytes from initdata populated in the FIFO using for loop
{
    I2C_putData(I2CA_BASE,s_oled128x64_initData[iter]);
}
I2C_putData(I2CA_BASE,0xA5);// Last command byte to light up the screen is the 27th byte.
I2C_sendStartCondition(I2CA_BASE);//A start condition can be sent by a master using I2C_sendStartCondition()
I2C_sendStopCondition(I2CA_BASE);//A start condition can be sent by a master using I2C_sendStartCondition()

}

Thank you for your time

Balaji.

  • The SME is currently unavailable to respond to this thread. Kindly expect a response in the next 2-3 days.

  • Hi Balaji,

    It looks the data is being overwritten in the I2C buffers. You can verify this by checking what the data is in both the buffers and on the data line itself between the first 16 bytes and the second 11 bytes which should show you if the first 16 bytes are transmitted / received properly. As for the data you have not labelled in the second image, is this data from the first transmission and/or some other known values or are they random? Are the interrupts being triggered / working correctly? When the I2C is in FIFO mode, the I2CCNT is not used but rather the TXFFST.

    I2C buffers need to be cleared before more data is written / read from and this information is in the TRM as well as software examples itself in more detail. Please precisely identify where the issue occurs in software and the steps taken for resolution, so I can better assist.

    Best Regards,

    Aishwarya

  • I could get the code working following the examples you have mentioned. The code that is sending the full 27 bytes is pasted below.

    The statement 

        while(I2C_getTxFIFOStatus(I2CA_BASE)!=I2C_FIFO_TX0){}//Wait till FIFO remaining bits is zero?

    ensures that the transmit FIFO gets empty before going for the next 11 bytes.

    By the way, simply putting a delay of 100ms after the the I2C_sendStartCondition() function call , before the

     I2C_sendStopCondition() also works...

    Code:

    void init_i2c_module(){
    
        // https://software-dl.ti.com/C2000/docs/C2000_driverlib_api_guide/f2837xd/html/modules/i2c.html#
    
        I2C_disableModule(I2CA_BASE);//Before initializing the I2C module, the user first must put the module into the reset state
    
        I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 10000, I2C_DUTYCYCLE_50);//the user must then call I2C_initMaster() which will configure the rate and duty cycle of the master clock.
    
        I2C_setDataCount(I2CA_BASE, 16);// Set data count must be before enable fifo
    
        I2C_enableFIFO(I2CA_BASE);
    
        I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);//I2C_setConfig() should be called to configure the behavior of the module
    
        I2C_setSlaveAddress(I2CA_BASE, 0x3C);
    
        I2C_enableModule(I2CA_BASE);
    
    
    
        I2C_putData(I2CA_BASE,0x00);// First byte: Command identifier 0x00 is the first byte, remaining 15 bytes are put in the FIFO using for loop below
    
        for (iter=0;iter<=14;iter++)// Remaining 15 bytes of the init data to fill up the FIFO
    
        {
    
            I2C_putData(I2CA_BASE,s_oled128x64_initData[iter]);
    
        }
    
        I2C_sendStartCondition(I2CA_BASE);
    
        while(I2C_getTxFIFOStatus(I2CA_BASE)!=I2C_FIFO_TX0){}//Wait till FIFO remaining bits is zero?
    
        //    DEVICE_DELAY_US(10000);
    
        I2C_sendStopCondition(I2CA_BASE);
    
    
    
        // Of the total 27 bytes, 16 sent earlier, 11 more are pending.
    
        I2C_setDataCount(I2CA_BASE, 11);
    
        for (iter=15;iter<=24;iter++)// 10 bytes from initdata populated in the FIFO using for loop
    
        {
    
            I2C_putData(I2CA_BASE,s_oled128x64_initData[iter]);
    
        }
    
        I2C_putData(I2CA_BASE,0xA5);// Last command byte to light up the screen is the 27th byte.
    
        I2C_sendStartCondition(I2CA_BASE);//A start condition can be sent by a master using I2C_sendStartCondition()
    
        while(I2C_getTxFIFOStatus(I2CA_BASE)!=I2C_FIFO_TX0){}//Wait till FIFO remaining bits is zero?
    
        I2C_sendStopCondition(I2CA_BASE);//A start condition can be sent by a master using I2C_sendStartCondition()
    
    }

  • Balaji,

    Glad to hear it. Out of curiosity, besides solving the issue, how does adding the 100 ms modify the time during and in between data transfers, if applicable? That step makes sense to me, but I wonder why 100 ms specifically was chosen.

    If you have no more queries, please resolved and close the thread, thank you.

    Best Regards,

    Aishwarya

  • The logic analyzer plot when using function call to check the FIFO status is 

    The logic analyzer plot when using delay function (20ms) to give time for FIFO to get empty before calling the function I2C_sendStopCondition() is 

    In this case, only the first 16 bytes get transmitted and the next batch of 11 bytes never start. There is the expected 20ms delay between start and stop of the transmission. 

    When I use 10 ms delay before calling I2C_sendStopCondition() after start function call, both the batches (16 bytes and 11 bytes) of transmission work. 

    I do not know why the 10ms delay works but the 20ms does not. If it is something obvious to somebody, please point out.

    Thank you for your time.