Below is the normal IIC transction.

The delay between two transction shall be 105ms.

But I face the bug that sometimes it will start the Write commnd very very closely, which is not expected.
Which may cause this bug? Other Interrupts?

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.
Below is the normal IIC transction.

The delay between two transction shall be 105ms.

But I face the bug that sometimes it will start the Write commnd very very closely, which is not expected.
Which may cause this bug? Other Interrupts?

Hello,
What are you using to trigger the I2C communication? What is your configuration that you're using to set up the peripheral?
sometimes it will start the Write commnd very very closely
Can you quantify what you mean by closely?
Best regards,
Omer Amir
trigger the I2C communication by invoke the below function period
void I2cWritePECMax20480_TmrDly(void)
{
uint32_t _uMDataBuf = 0;
uint32_t _uMdev_id = 0;
uint32_t _uMreg = 0;
uint32_t _uMcrc_data_out = 0;
uint32_t _uMcrc_data_in[3];
_uMdev_id = 0x39;
_uMreg = 0x28;
_uMDataBuf = 0x08;
_uMcrc_data_in[0] = ((_uMdev_id<<1) | 0x00);
_uMcrc_data_in[1] = _uMreg;
_uMcrc_data_in[2] = _uMDataBuf;
_uMcrc_data_out = PEC_CRC(_uMcrc_data_in,3);
//
// Setup number of bytes to send msgBuffer and address
//
I2C_setDataCount(I2CB_BASE, 3);
I2C_sendStopCondition(I2CB_BASE);
//
// Setup data to send
//
I2C_putData(I2CB_BASE, _uMreg);
I2C_putData(I2CB_BASE, _uMDataBuf);
I2C_putData(I2CB_BASE,_uMcrc_data_out);
//
// Send start as master transmitter
//
//I2C_setFIFOInterruptLevel(I2CB_BASE, I2C_FIFO_TX3, I2C_FIFO_RX16);
I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);
I2C_sendStartCondition(I2CB_BASE);
//I2C_sendStopCondition(I2CB_BASE);
DEVICE_DELAY_US(50000);
}
IIC init is below
I2C_disableModule(I2CB_BASE);
//
// I2C configuration. Use a 100kHz I2CCLK with a 33% duty cycle.
//
I2C_initMaster(I2CB_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_33);
I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);
I2C_setSlaveAddress(I2CB_BASE, 0x0039);
I2C_disableLoopback(I2CB_BASE);
I2C_setBitCount(I2CB_BASE, I2C_BITCOUNT_8);
I2C_setAddressMode(I2CB_BASE, I2C_ADDR_MODE_7BITS);
//
// FIFO configuration
//
I2C_enableFIFO(I2CB_BASE);
//
// Enable stop condition and register-access-ready interrupts
//
I2C_enableInterrupt(I2CB_BASE, I2C_INT_STOP_CONDITION |
I2C_INT_REG_ACCESS_RDY);
I2C_clearInterruptStatus(I2CB_BASE, I2C_INT_ADDR_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
I2C_setFIFOInterruptLevel(I2CB_BASE, I2C_FIFO_TX3, I2C_FIFO_RX16);
I2C_setEmulationMode(I2CB_BASE, I2C_EMULATION_FREE_RUN);
//
// Configuration complete. Enable the module.
//
I2C_enableModule(I2CB_BASE);Hello,
A few questions:
I am trying to compare your code to the Figure 33-7. I2C Master TX / RX Flowchart, as this provides a general guideline on how to use the I2C as the controller.
Best regards,
Omer Amir
- In line 21 of your first code snippet, why are you sending a stop condition
- Can you send me the status bits that are set for I2C when this extra write occurs?
I send a stop condition due to reference from TI's example. I2c_ex4_eeprom_polling. Does this stop result something unexpected?
I capture the extra write occurs using logic analyzer, if need the status bits, i shall add the interrupt to capture this extra write.
Which interrupt can capture this error? I need this info to do the I2C interrupt enable. Like below.
I2C_enableInterrupt(I2CB_BASE, I2C_INT_STOP_CONDITION |
I2C_INT_REG_ACCESS_RDY);
Another important information that in cpu2, have one ADC interrupt 90KHz, and it will take 4-5us.
I tried to disable this interrupt, that I2C bug will not happen.
But in this interrupt that is nothing with I2C. I do not find any connection with them.
Hello,
I've noticed you are creating many threads all on the same topic of I2C. Please try to keep all similar questions in one thread (if you need to, take time to compile and list the questions/problems you're having before posting instead of posting each one as a separate thread). As of now it looks like you've created a few threads all regarding I2C. This makes it very difficult to track and try to answer your questions.
I will go ahead and merge these now and try to answer your questions. Please avoid doing this in the future.
Best regards,
Omer Amir
Hello,
The second ACK((No-)Acknowledgement bit from receiver), does this receiver means Master?
The image is discussing I2C data transfer, so I believe the receiver is the target device external to the F2838x. However, I think this can apply either way; the F2838x or external I2C device can be the receiver, since you can have a controller or a target that's a receiver.
I send a stop condition due to reference from TI's example. I2c_ex4_eeprom_polling. Does this stop result something unexpected?
I looked at this example, but I don't see this sort of flow in the functions. Can you point out which function you're specifically copying from? The ones I've looked at seem to have the stop condition sent at the end of the communication, whereas your code has it set before the start condition is sent.
Which interrupt can capture this error?
There's no specific interrupt for this type of error that I know of. You can just read the status bits into a variable every time the I2C communication ends and have a breakpoint there; when the logic analyzer shows that the extra write occurred, look at the variable's value.
But in this interrupt that is nothing with I2C. I do not find any connection with them.
Is the I2C in an interrupt or just a normal function? The example you cited basing your code off does not have interrupts, it is using only polling, so this may not be ideal in a program where you have interrupts which might actively interrupt an I2C communication.
Best regards,
Omer Amir
The image is discussing I2C data transfer, so I believe the receiver is the target device external to the F2838x. However, I think this can apply either way; the F2838x or external I2C device can be the receiver, since you can have a controller or a target that's a receiver.
Got the meaning. Thanks.
I looked at this example, but I don't see this sort of flow in the functions. Can you point out which function you're specifically copying from? The ones I've looked at seem to have the stop condition sent at the end of the communication, whereas your code has it set before the start condition is sent.
From i2c_ex5_master_slave_interrupt
uint16_t I2C_MasterTransmitter(struct I2CHandle *I2C_Params)
{
uint16_t status;
uint32_t base = I2C_Params->base;
I2C_Params->numofSixteenByte = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL;
I2C_Params->remainingBytes = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL;
ASSERT(I2C_Params->NumOfDataBytes <= MAX_BUFFER_SIZE);
I2C_enableFIFO(base);
status = I2C_TransmitSlaveAddress_ControlBytes(I2C_Params);
if(status)
{
return status;
}
I2C_setDataCount(base, (I2C_Params->NumOfAddrBytes + I2C_Params->NumOfDataBytes));
I2C_sendStopCondition(base);
I2C_setFIFOInterruptLevel(base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);
I2C_enableInterrupt(base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
I2C_enableInterrupt(base, I2C_INT_TXFF);
I2C_clearInterruptStatus(base, I2C_INT_TXFF);
return SUCCESS;
}Is the I2C in an interrupt or just a normal function? The example you cited basing your code off does not have interrupts, it is using only polling, so this may not be ideal in a program where you have interrupts which might actively interrupt an I2C communication.
Just normal function, we use polling mode. Due to extra interrupt is forbidden in out project. (Project SW architecture defined)
We want to know how the 90KHZ ADC interrupt affect the I2C communication, will it make it unfuncational ? How?
We find the root cause is that when have the ADC interrupt and continue invoke the below code will result the bug.
I2C_sendStartCondition(I2CB_BASE);
I2C_sendStopCondition(I2CB_BASE);
We can reproduce the bug by below code, add 1us delay between
I2C_sendStartCondition(I2CB_BASE);
I2C_sendStopCondition(I2CB_BASE);
void I2cWritePECMax20480_TmrDly(void)
{
uint32_t _uMDataBuf = 0;
uint32_t _uMdev_id = 0;
uint32_t _uMreg = 0;
uint32_t _uMcrc_data_out = 0;
uint32_t _uMcrc_data_in[3];
_uMdev_id = 0x39;
_uMreg = 0x28;
_uMDataBuf = 0x08;
_uMcrc_data_in[0] = ((_uMdev_id<<1) | 0x00);
_uMcrc_data_in[1] = _uMreg;
_uMcrc_data_in[2] = _uMDataBuf;
_uMcrc_data_out = PEC_CRC(_uMcrc_data_in,3);
//
// Setup number of bytes to send msgBuffer and address
//
I2C_setDataCount(I2CB_BASE, 3);
//
// Setup data to send
//
I2C_putData(I2CB_BASE, _uMreg);
I2C_putData(I2CB_BASE, _uMDataBuf);
I2C_putData(I2CB_BASE,_uMcrc_data_out);
//
// Send start as master transmitter
//
//I2C_setFIFOInterruptLevel(I2CB_BASE, I2C_FIFO_TX3, I2C_FIFO_RX16);
I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);
I2C_sendStartCondition(I2CB_BASE);
DINT;
DRTM;
DELAY_US(1);
I2C_sendStopCondition(I2CB_BASE);
DEVICE_DELAY_US(50000);
}

And we try to merge the two I2C_sendStartCondition and I2C_sendStopCondition into one code.
It will work out and fix the bug.
HWREGH(I2CB_BASE + I2C_O_MDR) |= (I2C_MDR_STT |I2C_MDR_STP);
If any expert from TI side could help confrim this point it will be appreciated.
Hello,
When add the I2CB in CPU2, Sometimes show that NACK happens.
I want to know the root cause why the NACK happen.
Which registers shall I check to confirm the root cause ?
It looks like you're trying to use I2C in controller transmitter mode and receiving NACK from target device. It seems like the target I2C device is processing the information already sent and holding the F2837xD I2C from sending more data bytes. This is expected behavior and not a device bug. NACK signal is from the I2C target device, so you will need to look at the I2C target device you are interfacing to, not the F2837xD device.
From i2c_ex5_master_slave_interrupt
The code snippet you cite does not send any start condition after a stop condition, it looks like this function is specifically used for configuring the device as a controller transmitter, it's not actually sending anything within that function.
We want to know how the 90KHZ ADC interrupt affect the I2C communication, will it make it unfuncational ? How?
You will need to configure some output toggling or watch variables to confirm, but it may be the case that the ADC interrupt is interrupting the I2C communication and causing some different behavior. I'm not sure how exactly this is happening within the design, but from the sound of it, when you don't use interrupts while using the polling I2C there is no problem. I will confirm with some interrupt experts to see if they know more about this, but for now you can confirm whether this is the situation that's happening.
If any expert from TI side could help confrim this point it will be appreciated.
Is this a separate question from the earlier one? If so, can you please clarify what the actual question is? I'm not sure I understand from your latest post.
Best regards,
Omer Amir
We can reproduce the bug by below code, add 1us delay between
This is the point i want that TI's expert to confirm
And we try to merge the two I2C_sendStartCondition and I2C_sendStopCondition into one code.
It will work out and fix the bug.
HWREGH(I2CB_BASE + I2C_O_MDR) |= (I2C_MDR_STT |I2C_MDR_STP);
Hello,
I've not heard of a customer with this kind of issue before. I will try to reach out to some other experts to understand why another target address is sent because of the presence of the ADC interrupt and get back to you tomorrow.
Best regards,
Omer Amir
Hello,
You need to look in your code for any time the start condition is sent (either by directly modifying the register or using a driverlib function). The I2C only sends another start condition because somewhere during your transmission you are sending another start condition. If you only have the one start condition being sent, you can read the Bus Busy bit in the I2CSTR register to see if it's still in the middle of a transmission when you're about to send another start condition.
Best regards,
Omer Amir
I am quite sure that there is no another start condition sending.
And this I2CB only have one master F28386 and one slave.
I put the reproduced bug step above.
Someone using the I2C polling mode and with the other interrupt may have the same bug.
Hope this will help.
Hello,
I am quite sure that there is no another start condition sending.
Please double-check, you can also read the Bus Busy bit in the I2CSTR register to see if it's still in the middle of a transmission when you're about to send another start condition.
I put the reproduced bug step above.
Someone using the I2C polling mode and with the other interrupt may have the same bug.
This has not been reported by any other customers, so there is no known problem/fix for this. You will need to do some work on your side to verify whether there is somehow another start being sent or if your code is sending another start condition in the middle of the previous transmission.
Best regards,
Omer Amir