Hello,
I'm working with the Delfino TMX320F28377D and I'm implementing the I2C communication
but I'm having problems when I try to read near to the maximum speed 390KHz.
void I2CA_Init(void)
{
// I2C Module Clock = SysClockOut/(I2C_IPC+1)
I2caRegs.I2CPSC.all = 18;
I2caRegs.I2CCLKL = 10; // I2C Clock Low Time
I2caRegs.I2CCLKH = 5; // I2C Clock High Time
I2caRegs.I2CIER.all = 0x00; //first, clear the Interrupt Enable Register
I2caRegs.I2CIER.bit.ARDY = 1; //Register access ready interrupt
I2caRegs.I2CIER.bit.SCD = 1; //Stop condition detection
I2caRegs.I2CIER.bit.RRDY = 1; //Receive Data Ready
//I2caRegs.I2CIER.bit.ARBL = 1;
I2caRegs.I2CMDR.all = 0x0020; // Clear the Mode Register and enable I2C Module
I2caRegs.I2CFFTX.all = 0x00; // first, clear the FIFO Rx register and then
//// set the individual bits.
I2caRegs.I2CFFTX.bit.I2CFFEN = 1; // Enable FIFO Mode
I2caRegs.I2CFFTX.bit.TXFFRST = 1; // Enable Transmit FIFO (16 byte Tx fifo)
I2caRegs.I2CFFTX.bit.TXFFIL = 0; // interrupt when Tx FIFO is empty.
I2caRegs.I2CFFTX.bit.TXFFIENA = 0; // Disable Tx FIFO interrupt until Ready to transmit.
I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1; // Clear the TXFFINT flag.
I2caRegs.I2CFFRX.all = 0x00;
I2caRegs.I2CFFRX.bit.RXFFRST = 1; // Enable Rx FIFO (16 byte Rx fifo)
I2caRegs.I2CFFRX.bit.RXFFINTCLR = 1;
// level is = I2C_RX_INTERRUPT_LEVEL.
I2caRegs.I2CFFRX.bit.RXFFIENA = 0; // Disable Rx FIFO interrupt.
For the first access to the EEPROM the settings of the I2C for address the devive and write the read address are the next:
I2caRegs.I2CCNT = 2; // Load Byte count.
I2caRegs.I2CDXR.all = ByteHigh; // high byte of the register to be read.
I2caRegs.I2CDXR.all = ByteLow; // low byte of the register to be read.
//SET --> I2CMDR_IRS | I2CMDR_STT | I2CMDR_MST | I2CMDR_TXR
// I2C Module Enabled
// Generate START condition
// MASTER mode
// TRANSMIT mode
I2caRegs.I2CMDR.all = 0x2620;
Then in the ISR when ARDY trigers I send a start condition again and I check for the SCD and RRDY interrupts.
//ISR Rutine:
interrupt void i2c_int1a_isr(void) // I2C-A
{
uint16_t IntSource;
uint8_t rxFifoCounter, idx;
// Read interrupt source
IntSource = I2caRegs.I2CISRC.all;
switch(IntSource)
{
case I2C_NO_ISRC: // =0 None
break;
case I2C_ARB_ISRC: // =1 Arbitration lost
break;
case I2C_NACK_ISRC: // =2 No-acknowledgment condition detected
break;
case I2C_ARDY_ISRC: // =3 Registers ready to be accessed
if(I2caRegs.I2CSTR.bit.NACK == 0) // Check NACK from device
{
I2caRegs.I2CCNT = ByteCount; // Set up the number of bytes to recive.
//SET --> I2CMDR_IRS | I2CMDR_STT | I2CMDR_STP| I2CMDR_MST | I2CMDR_TXR
I2caRegs.I2CMDR.all = 0x2C20; // Send "repeated" Start with Read (TRX off) and Stop.
ackNotReceived = 0; // Clear ACK Flag
}
else
{ // NACK BIT RECEIVED (I2C FAIL)
I2caRegs.I2CMDR.bit.STP = 1; // Send stop condition
I2caRegs.I2CSTR.bit.NACK = 1; // Clear NACK Flag
}
break;
case I2C_RX_ISRC: // =4 Receive data ready
rxFifoCounter = I2caRegs.I2CFFRX.bit.RXFFST;
for(idx=0;idx<rxFifoCounter;idx++)
{
ReadReg[I2cIndex++] = I2caRegs.I2CDRR.all; // Read data recived and increment index
}
break;
case I2C_TX_ISRC: // =5 Transmit data ready
transmitDataInCourse = 0;
break;
case I2C_SCD_ISRC: // =6 // When stop condition is detected clear dataNotReceived Flag
dataNotReceived = 0; // to avoid timeout timer.
if(I2caRegs.I2CSTR.bit.NACK == 0) // NACK Received
{
ackNotReceived = 0;
}
else // NACK BIT RECEIVED (I2C FAIL)
{
I2caRegs.I2CMDR.bit.STP = 1; // Send stop condition
I2caRegs.I2CSTR.bit.NACK = 1; // Clear ACK Flag
}
break;
case I2C_AAS_ISRC: // =7 Addressed as slave
break;
default:
asm(" ESTOP0"); // Halt on invalid number.
break;
}
// Enable future I2C (PIE Group 8) interrupts
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP8;
}
It seems that works fine but some times when I repeat a read sequence several times, I can see in the I2C_RX_ISRC the RX FIFO have more than one byte and depends on the time I2cIndex doesn't match with the real data index. It seams like some interrupt doesn't triger.
Has somebody had a similar experience?
Thanks.