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.

TPSM846C23EVM-806: Why IC2 needs certain delay in TPSM846C23EVM-806 for every data byte transmission?

Part Number: TPSM846C23EVM-806
Other Parts Discussed in Thread: TPSM846C23

Hi, 

I am trying to establish IC2 communication between TPSM846C23EVM-806 and TIVA TM4C1294XL to control the output voltage of  the TPSM846C23EVM whose default voltage is 0.6V. I would like to set it to 0.35 V.  Here is the part of my code for that. The code works fine as you can see the snapshot of the logic analyzer below. My question is that it does not work without the time delay (SysCtlDelay(50)) that I included after every data byte transition. It took a while from me to figure out that I need to include a certain delay but I do not know the main reason? I was thinking that checking the BUSY bit should be enough but apparently it is not. Could you please let me know the reason for the need of a certain delay after every data byte transmission. Thanks a lot...

Note: The second snapshot of the logic analyzer shows the results after removing the time delay. 

int
main(void)
{

uint32_t ui32SysClkFreq;
uint8_t VOUT_COMMAND[3];

ui32SysClkFreq = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
//
// Wait for the Peripheral to be ready for programming
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOG));

//
// Stop the Clock, Reset and Enable I2C Module
// in Master Function
//
SysCtlPeripheralDisable(SYSCTL_PERIPH_I2C1);
SysCtlPeripheralReset(SYSCTL_PERIPH_I2C1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

//
// Config pin muxing for I2C and select I2C function for these pin
//
GPIOPinConfigure(GPIO_PG1_I2C1SDA);
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);
GPIOPinConfigure(GPIO_PG0_I2C1SCL);
GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);

//
// Wait for the Peripheral to be ready for programming
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1));

I2CMasterInitExpClk(I2C1_BASE, ui32SysClkFreq, true); // The rate of the clk for I2C1 module is set to 400 Kbps.

I2CTxFIFOFlush(I2C1_BASE); // Flush the transmit (TX) FIFO.

VOUT_COMMAND[0] = 0x21; // register to be written.
VOUT_COMMAND[1] = 0xB4; // LSB
VOUT_COMMAND[2] = 0x00; // MSB -- sets the output voltage to (0x00B4) 180 * 2^-9 = ~ 0.35 V.

while (1)
{
I2CMasterSlaveAddrSet(I2C1_BASE, TPSM846C23_I2C_ADRESSS, false); // I2C1 Master is initiating a write to the slave at address of TPSM846C23_I2C_ADRESSS.

I2CMasterDataPut(I2C1_BASE, VOUT_COMMAND[0]); // Place the data (register address) to be sent in the data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Initiate send of data from Master to Slave
SysCtlDelay(50);
while(I2CMasterBusy(I2C1_BASE)); // Delay until transmission completes

I2CMasterDataPut(I2C1_BASE, VOUT_COMMAND[1]); // Place the data (MSB) to be sent in the data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); // Initiate send of data from Master to Slave
SysCtlDelay(50);
while(I2CMasterBusy(I2C1_BASE)); // Delay until transmission completes

I2CMasterDataPut(I2C1_BASE, VOUT_COMMAND[2]); // Place the data (MSB) to be sent in the data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); // Initiate send of data from Master to Slave
SysCtlDelay(50);
while(I2CMasterBusy(I2C1_BASE)); // Delay until transmission completes

}

}

FIRST SNAPSHOT (WITH TIME DELAY)

SECOND SNAPSHOT (WITHOUT TIME DELAY)

  • Hi Fatih,

    I just wanted to let you know that I am looking into your question. I need some time to analyze the details you have provided, but I will try to get back to you within a day's time.

    Regards,
    Kris

  • Fatih,

    The first thing that jumps out to me in the second waveform is that even the analyzer is missing the stop bits associated with the last 2 transactions.

    That's not between every byte, but between the Stop bit of one transaction and the start bit of the next.  It looks like without that wait, the transactions run together and there is a missing stop bit.

    The other issue I see is that the programming sequence in the bottom is sending 0x84 as the command code, which is getting NACKed because the TPSM846C23 does not support command code 0x84 (RESERVED).  When command code 0x21 is sent, the analyzer shows an ACK, but after sending the command code, the data shows a start bit with no stop bit.  It seems like there is an issue with the data coming from the I2C master.

  • Hi Peter,

    The analyzer is missing the stop bits associated with the last 2 transactions but it is not supposed to because I do execute the following code:

    I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); // Initiate send of data from Master to Slave

    Similar to the other transmissions the data bytes are not transmitted in order when I do not add the time delay.

    Actually it is 0XB4 that I am sending to set the output voltage to 0.35V.   It is getting NACKed because after the slave address the register address is missing although it is there is my code, which is 0x21.

     

    VOUT_COMMAND[1] = 0x21; // register to be written.

    VOUT_COMMAND[2] = 0xB4; // LSB

    VOUT_COMMAND[3] = 0x00; // MSB -- sets the output voltage to (0x00B4) 180 * 2^-9 = ~ 0.35 V.

     

    My question here is why do we need to add a delay. Is there any other way to make sure the slave will receive each data byte properly. I do not want to use delay between each transition.


    Thanks in advance...

  • Fatih,

    I am one of the factory applications experts on the TPSM846C23, but from what I can tell the issue here is not in the TPSM846C23.  Based on the data-bytes being sent to the TPSM846C23, it is responding correctly, but the bytes being transmitted by the TM4C1294XL are not matching the expectation without the delay.  I will see if I can find an expert on the TM4C1294XL to assist you with your issue.

  • Fatih,

    We have found a TIVA expert, and asked them to review your issue, unfortunately they are currently out of the office, but they are expected back tomorrow.  I don't know how long it will take them to get to this issue.  In the mean-time, we found this thread:

    https://e2e.ti.com/support/microcontrollers/other/f/908/p/326687/1146925#1146925

     

    Which suggests that the issue could be a problem with the code executing too fast and the I2C not being busy yet when the code reaches the  while statement without a system delay.  The suggestion is to add a variable delay between the I2C Control burst command line and the While Busy with a "while not busy" to ensure that the I2C Master is busy before the code moves on to the "while busy"

     

    You can review this other thread, and try that solution while we are waiting for the TIVA expert to return to the office.

  • Hello Faith,

    As Peter has indicated on his post, rather than using a delay, you should try and use the following sequence:

    while(!I2CMasterBusy(I2C1_BASE));
    while(I2CMasterBusy(I2C1_BASE));

    We often see this extra while loop check being needed on the TM4C129x devices for I2C operation. The advantage of this is that you don't have a static delay and will give you the fastest response time for the I2C commands to be properly processed.

    Let us know if that allows the system to work correctly without the delay.

  • Hi Ralph, 

    It solved the issue. Thank you so much...