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.

CCS/TMS320F28335: I2C module: Stuck waiting for Bus Busy bit to be cleared

Part Number: TMS320F28335
Other Parts Discussed in Thread: BQ34110

Tool/software: Code Composer Studio

Hello,

I am currently having trouble using the I2C module on the F28335 MCU. I have been using the following Rx and Tx functions: 

RxTxReg.txt
Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Uint16 I2CWriteReg(Uint16 reg, Uint16 data[], Uint16 data_size)
{
Uint16 i, Status;
Status = I2C_SUCCESS;
//
// Wait until the STP bit is cleared from any previous master communication
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
//
if (I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}
//
// Setup slave address
//
I2caRegs.I2CSAR = slaveAddress;
//
// Check if bus busy
//
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CCNT = 1 + data_size;
//
// Set up as master transmitter
// FREE + MST + TRX + IRS
//
I2caRegs.I2CMDR.all = 0x6E20;
//
// Setup number of bytes to send
// == register byte + (# of data[] buffer bytes)
//
// I2caRegs.I2CCNT = 1 + data_size;
//I2caRegs.I2CMDR.bit.STT = 0x1; // Send START condition
//I2caRegs.I2CMDR.bit.STP = 0x1; // STOP condition will be
// generated when I2CCNT is zero
//
// I2C module will send the following:
// register byte ==> data bytes ==> STOP condition
//
while(!I2caRegs.I2CSTR.bit.XRDY){} // Make sure data
// is ready to be written
I2caRegs.I2CDXR = reg;
#if NACK_CHECK // check if NACK was received
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CMDR.bit.STP = 1;
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
Status = I2C_ERROR;
return Status;
}
#endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The problem is, when trying to use the I2CReadReg function, sometimes it will work as expected, but sometimes the data line will immediately be stuck high and the clock line will be stuck low. Even if it does work initially, it will usually eventually get stuck as well. The bus busy error will be returned. I have tried incorporating a timeout condition in main that will reset the I2C module if the BB, XRDY, RRDY flags etc are stuck being polled, but this doesn't seem to work. Could anyone give me some advice? Initially we thought it might be a noise issue (we are testing in a relatively noisy environment) but we are not so sure anymore. Information that may also be of interest:

-When the I2C lines are actually Tx/Rx'ing, the low voltage is not always 0 V, sometimes 700 mV (High is 3.3V).

-In main, we are using a write function once, then we are looping many read functions. It seems that on the first read function, the status error being returned is from the MCU being stuck polling for either XRDY or RRDY, but the rest of the read functions are returning the bus busy status error. 

-Transmitting a specific write command to the slave (which resets the slave) will immediately hang the bus line 100% of the time. Transmitting any other write command will hang the bus line exactly 50% of the time (alternating between hanging the line and not hanging the line). Interestingly enough, stepping through the reset command line by line will not hang the bus line. 

  • Hi Colin,

    Have you probed the bus to see what the waveforms look like when this issue occurs? You may need to try probing at both the Master and Slave sides in case only one side is not receiving correctly. Feel free to post screenshots of the waveforms here if you'd like me to look at them.

    What device are you using as the slave? In your code, are you using the I2C FIFO mode, or non-FIFO?

    Best,

    Kevin

  • Hi Kevin,

    Sorry for not replying. We were using the non-FIFO mode with a BQ34110 as a slave, and both sides seemed to be receiving correctly. Just an update on the problem: we couldn't actually find the source of the problem (it is likely noise, but this is hard to verify). We decided instead to just tell the microprocessor to quit the read or writing function if it got hung up while polling for a flag for too long, and then reset the I2C module if the bus lines themselves were hanging for too long. This might not be the best course of action, but it seems to work for the time being. Thanks for your help.