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.

I2C Master Random R/W bit flips

Other Parts Discussed in Thread: MSP430F5342, TLV320AIC3204

I am seeing an issue with the C5505 DSP I2C configured as the lone master on the bus where ~1 in every 1000 or so transactions the C5505 will flip the R/W unexpectedly sending out a read first instead of a write then read during a repeated start type transaction.

Any thoughts as to what would cause the master to do this?

My test setup is as follows

Every 1 sec

I2C_read(&RxBuf[0],11,0x48,&regnum, 1,1,CSL_I2C_DEFAULT_STTSTP ,CSL_I2C_MAX_TIMEOUT,1);

On the bus are a few I/O expanders and an MSP430F5342. The master, using a repeated start writes a 'register' in the 430 (0x0B), then reads back a pre-determined number of bytes (11) for this register. During this loop, no other device on the bus is being written to or read from. This occurs for any combination of register values and number of response bytes.

Screenshots:

  1. Correct write from C5505 to MSP430
  2. Correct response from MSP430 following repeated start and read from C5505 (same transaction as above)
  3. C5505 incorrectly puts a read on the bus first instead of a write

  • Hi, 

    I do not think, we had come across any such issue earlier. I have few more questions. 

    • Are you using CSL or this is your own software. 
    • Are you observing this issue in multiple C5505 devices.

    Can you clarify on the above. 

    Regards

     Vasanth

     

  • Vasanth,

    Yes, we have seen this problem across multiple C5505s. We are using CSL v3.03 and the function mentioned has not been modified from stock CSL state.

    Thanks,

    Hunter

  • Hi Hunter,

    I have few more followup questions.

    • After how many transfers this R/W bit flip issue is occurring ? Is this failure observed consistently around the same transfer count.
    • What is the i2C clock frequency ~260Khz ?
    • I believe no I2C configuration is happening while this transfer is being done. Confirm?
    • Since DSP I2C is in master mode, did you try enabling digital loop back and check ?
    • If Possible isolate DSP I2C from other device and test this independently to ensure no contention on the bus at any time.
    • When continuous writes are performed is this behavior observed?
    • I understood that this is happening in multiple devices, are there devices where this issue is not observed ?
    • Can the issue be reproduced on TI hardware platform ?

    Pl let me know.

    Regards

     Vasanth

     

  • HI Vasanth,

    Thank you for a quick reply

    1. This occurs on average about 2/1000 transactions
    2. The clock frequency has been varied from 260->400kHz and seems to not have an effect
    3. Correct, this is under normal operation after boot up
    4. We have not, I can run a test today.
    5. Currently, I am lifting devices off the bus one at a time and will let you know the results.
    It occurs under two conditions we have been testing mainly the second
    1. Normal operation, all devices talking on the bus
    2. Only the msp430 talking on the bus, i.e. repeatedly calling the read function
    • It seems to occur more often on some devices, but we don't have any it is not occurring on
    • We can try this. I will dig up a developer board.

    Thanks,

    Hunter

  • Hi Hunter,

    We will wait to hear from you on (4) & (5).

    Also let us know if this can be recreated on TI platform.

    Regards

     Vasanth

  • Hunter,

    Please update this thread when you determine the cause. I have seen an occasional bus hang (1 in 10,000?) because of an occasional extra clock during a read. (Addressed slave holds SDA low.) I haven't caught it with a scope, but it shows up occasionally in my TotalPhase Beagle I2C analyzer. I have a C5535 as the master, and the slaves are TLV320AIC3204 (codec) and two ATtiny88 microcontrollers. All are running at 1.8V. I only see it while reading one of the ATtinys, but there isn't really a need to read the codec. For the time being, if there's no I2C activity for 200 ms (normally every 50 ms), I simply reset the I2C bus at both ends (both the DSP and ATtinys). Fortunately I don't need to do a read very often, maybe once per second to check the battery voltage.

    -Steve
  • Vasanth,

    We performed many tests with just about every configuration of different devices on and off the bus and were still seeing the issue. We began to take a close look at the CSL. I placed traces (using a numbering scheme and printf at the end as to not introduce extra delays) in the I2C_read routine to determine the paths taken through the routine. This looked good. Further investigating, I added some code to verify all register read/writes after they were performed. I found a few odd behaviors.

    1.  In the data receive loop, I placed a register read on the MST mode bit to ensure it was still set. 1~1,000 transaction this would fail (MST had been cleared), and the loop would timeout. When this was detected if I set the MST mode bit back to 1 the transaction would continue successfully as if nothing had happened.

    2. At the beginning of the routine, the TRX mode bit is set after the start bit is sent when in master mode. The random R/W flipped seemed to logically follow that this bit was not getting set correctly (thus the TRX mode was 0, the state the routine left it in after there previous transaction). I applied the same verification code to read back TRX after it was set. Indeed here every once in a while the bit would read back 0 after being set. If it wrote it again, the transaction would not fail. I also noticed that if I moved the TRX set before the start bit was set it would not fail on a subsequent read of the TRX bit.

    I'm not really sure what this behavior points to. But the bus seems to be much more stable after moving the TRX bit set as described in 2. and checking that the MST bit is always set before reading a byte.

    I have not tried loopback mode yet, but I will write the code to perform loopback with the register checking code to see if I see similar behavior.

    Thoughts?

    Hunter

  • Hunter,

    Below are my response.

    #1: Did STOP condition occurred while it was master ?  MST is automatically changed from 1 to 0 when the I2C master generates a STOP condition.

    #2: This Register bit TRX shouldn’t change unless its written with new value, were you able to capture and observe the previous writes done on ICMDR Register (I2C Mode Register) , when was this register last written and what was the written value.

    Regards

     Vasanth


  • Vasanth,

     #1 I do not see a stop condition on the scope or in the ICMDR.

    #2 I have seen it where both the TRX bit and the start bit are being set, but the if I immediately read them back they are not set. When this occurs, the routine runs through its operation normally but nothing is output on the bus until the routine reaches the receive portion of the repeated start transaction. At which point I believe it is writing the second have of the transaction correctly, but failing because first part of the transaction is missing.

    S, 48W, 0x0B, S, 48R, 0x01, 0x02 etc....

    I believe what is happening it fails to write S, 48W, 0x0B (either because the TRX is not set or the start bit was not sent, not sure), but then successfully writes S, 48R, making it appear as the R/W bit has been flipped. 

    As in mentioned in the previous post, moving the Tx mode set, into the first if(masterMode == true), but before the start bit is set seems to correct the issue.

    Code from the CSL, i removed all the comments to save space

    if(masterMode == TRUE)

    {

    CSL_FINS(i2cHandle->i2cRegs->ICSAR, I2C_ICSAR_SADDR, slaveAddr);

    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_MST, SET);

    //Moving here corrects the issue

    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_TRX, SET);

    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_STT, SET);

    }

    else

    {

    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_MST, CLEAR);

    }

    //This is where it is normally set

    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_TRX, SET);

     

    If I'm understanding the flow correctly, this routine assumes the TRX bit is set when it starts because the slave addr is written to the bus immediately following the STT set but the TRX bit is not set until the next line. Is this a safe assumption? If you run two of these transactions back to back the routine leaves the TRX bit cleared at the end, but assumes it to be set when the second transaction runs.

    Hunter

  • Hunter,

    Below are my comments with respect to your earlier findings on 1 and 2.

    #1. If stop condition doesn't occur then MST bit shouldn't get cleared automatically. This needs to be further investigated, logging RM, STT and STP bits and along with other I2C status registers might help.

    #2.  If the I2C peripheral is a master, it begins as a master-transmitter and typically, transmits an address for a particular slave. This is what is being done in the I2C CSL code you had presented. Basically its configuring I2C in master mode and  set transmitter bit.  I also do not see any issue in your modified code.

    Later in the same read routine (as you would have seen), for the actual read - TRX bit is cleared and other read related configuration is done then actual I2C reads are performed.

    With respect to your understanding on the flow; " this routine assumes the TRX bit is set when it starts because the slave addr" -  No this will not be the case, until the TRX bit is set.

    Hope this information( on #2) helps/clarifies. Also let us know your findings on #1 (ie logging I2C registers).

    Regards

     Vasanth

  • Vasantha,

    Could you clarify which register reads/writes I should try not using CSL FINS/FEXT for? 

    When logging the registers the normal state of the ICMDR during the read loop is 0x0420, after detecting the MST bit not set the register reads back as 0x0020.

    Likewise, the ICSTR is 0x3C38 during normal operation and 0x3431 after detecting the MST bit not set.

    Also can you clarify when the address gets sent on the bus and the TRX bits affect on the address sent? I see it getting sent immediately after setting the STT bit, with the 8th bit written being representative of the state of TRX bit. So if the state of the TRX bit is 0 when calling the I2C_Read routine it will write address with the read r/w set high. This fact along with your comment "no this will not be the case, until the TRX bit is set" leads me to understand that either I need to modify the code as I showed, or set the TRX bit before calling I2C_read? Am I understanding correctly?

    Hunter

  • Hunter,

    Could you clarify which register reads/writes I should try not using CSL FINS/FEXT for? 

    Vasanth: Ignore this for time being (not suspecting this ).

    When logging the registers the normal state of the ICMDR during the read loop is 0x0420, after detecting the MST bit not set the register reads back as 0x0020.

    Likewise, the ICSTR is 0x3C38 during normal operation and 0x3431 after detecting the MST bit not set.

    Vasanth: Looks like stop condition occurred (SCD bit is set here), can you check and reconfirm. Also, overrun interrupt has occurred, is previous ICDRR read correctly ?

    Also can you clarify when the address gets sent on the bus and the TRX bits effect on the address sent? I see it getting sent immediately after setting the STT bit, with the 8th bit written being representative of the state of TRX bit. So if the state of the TRX bit is 0 when calling the I2C_Read routine it will write address with the read r/w set high. This fact along with your comment "no this will not be the case, until the TRX bit is set" leads me to understand that either I need to modify the code as I showed, or set the TRX bit before calling I2C_read? Am I understanding correctly?

    Vasanth: As per my understanding, if STT 1 = In master mode, setting STT to 1 causes the I2C to generate a START condition on the I2C-bus. As seen in the initialization procedure (2.11 C5505 I2C user guide),TRX is configured before STT bit been set. So your modified code looks ok to me.

    Regards

     Vasanth