Hi, I am using I2C on TMS320F28069 to write and read multiple devices e.g. I2C to One Wire Bridge, I2C to IO Expander etc. I want to Write and Read as follows.
S AD,Wr [A] WCFG [A] CF [A] Sr AD, Rd, [A] [CF] A\ P
// [ ] indicates from slave
//WCFG - Write config register address
// CF - configuration byte to write
// AD - Address
// Sr - Repeat Start
When I write alone with out Rd i.e.
S AD,Wr [A] WCFG [A] CF [A] A\ P
The data sent out on SDA is perfect
but when I do
S AD,Wr [A] WCFG [A] CF [A] Sr AD, Rd, [A] [CF] A\ P
The read after write over writes the I2caRegs.I2CDXR register. I tried putting delay in between Write and then Read. It simply is sort of ignored and the over right continues. Plz give some idea or pointers on what to check.
The code is
void I2CAInit(void){
// Initialize I2C
I2caRegs.I2CSAR = 0x0050;
I2caRegs.I2CPSC.all = 10; // Prescaler - need 7-12 Mhz on module clk,Here = 30M/(6+1) = 4.28 Mhz
I2caRegs.I2CCLKL = 10; // Specify Space, must be non zero
I2caRegs.I2CCLKH = 10; // Specify Mark, must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended
I2caRegs.I2CFFTX.all = 0x6021; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFTX.bit.TXFFIENA = 1;
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT
//I2caRegs.I2CFFTX.all = 0x0000; // Disable FIFO mode and TXFIFO
//I2caRegs.I2CFFRX.all = 0x0000; // Disable RXFIFO, clear RXFFINT,
return;
}
int16 B1WWrConfig(Uint16 Config){
// Write configuration (Case A)
// S AD,0 [A] WCFG [A] CF [A] Sr AD,1 [A] [CF] A\ P
// [] indicates from slave
// CF configuration byte to write
I2C.MsgBuffer[0]=B1W_WCFG;
I2C.MsgBuffer[1]=Config;
I2C.NumOfBytes=2; //Number of data bytes, Address not included
I2CAWrite(&I2C);
msec(100);
I2C.MsgStatus = I2C_MSGSTAT_RESTART;
I2C.NumOfBytes=1;
I2CARead(&I2C);
msec(5);
if((I2C.MsgBufferRx[0] == (Config&0x0F) ))return(0);
else return(-1);
}
Uint16 I2CAWrite(I2CMSG *msg){
Uint16 i;
// 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;
while(I2caRegs.I2CMDR.bit.STP);
msg->WrDone = 1;
I2caRegs.I2CSAR = msg->SlaveAddress;
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)return I2C_BUS_BUSY_ERROR;
I2caRegs.I2CCNT = msg->NumOfBytes;
I2caRegs.I2CFFTX.bit.TXFFIL = msg->NumOfBytes;
for (i=0; i<msg->NumOfBytes; i++){
I2caRegs.I2CDXR = *(msg->MsgBuffer+i);
}
// Send start as master transmitter
if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP){
}
//I2caRegs.I2CMDR.all = 0x6E20; //Run Free, Sent Start,Stop,Master Mode, Transmit mode, Module enabled
I2caRegs.I2CMDR.all = 0x6E20; //Run Free, Sent Start,Stop,Master Mode, Transmit mode, Module enabled
//I2caRegs.I2CMDR.bit.RM=1; // Repeat mode
//I2caRegs.I2CMDR.bit.STP=1;
//while(I2caRegs.I2CSTR.bit.XRDY == 1){}
//while(I2caRegs.I2CSTR.bit.BB == 1){}
//while(msg->WrDone);
return I2C_SUCCESS;
}
Uint16 I2CARead(I2CMSG *msg){
// 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;
while(I2caRegs.I2CMDR.bit.STP);
I2caRegs.I2CSAR = msg->SlaveAddress;
msg->RdDone=1;
if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP){
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)return I2C_BUS_BUSY_ERROR;
I2caRegs.I2CCNT = msg->NumOfBytes;
I2caRegs.I2CDXR = 0;
I2caRegs.I2CMDR.all = 0x2620; // Send data to setup EEPROM address
}
else if(msg->MsgStatus == I2C_MSGSTAT_RESTART){
I2caRegs.I2CCNT = msg->NumOfBytes; // Setup how many bytes to expect
I2caRegs.I2CDXR = 0;
I2caRegs.I2CMDR.all = 0x2C20; // Send restart as master receiver
}
//while(I2caRegs.I2CSTR.bit.BB == 1 || I2caRegs.I2CSTR.bit.XRDY == 0)
//while(I2caRegs.I2CSTR.bit.BB == 1);
//while(I2caRegs.I2CSTR.bit.RRDY ==1);
//while(msg->RdDone);
return I2C_SUCCESS;
}
interrupt void i2c_int1a_isr(void){
Uint16 IntSource, i;
// Read interrupt source
IntSource = I2caRegs.I2CISRC.all;
// Interrupt source = stop condition detected
if(I2caRegs.I2CFFTX.bit.TXFFINT){
I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;
I2C.WrDone=0;
}
if(IntSource == I2C_SCD_ISRC){
// If completed message was writing data, reset msg to inactive state
if (I2C.MsgStatus == I2C_MSGSTAT_WRITE_BUSY){
I2C.MsgStatus = I2C_MSGSTAT_INACTIVE;
}
else {
// If a message receives a NACK during the address setup portion of the
// EEPROM read, the code further below included in the register access ready
// interrupt source code will generate a stop condition. After the stop
// condition is received (here), set the message status to try again.
// User may want to limit the number of retries before generating an error.
if(I2C.MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY){
I2C.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
}
// If completed message was reading EEPROM data, reset msg to inactive state
// and read data from FIFO.
else if (I2C.MsgStatus == I2C_MSGSTAT_READ_BUSY){
I2C.MsgStatus = I2C_MSGSTAT_INACTIVE;
for(i=0; i < I2C.NumOfBytes; i++){
I2C.MsgBufferRx[i] = I2caRegs.I2CDRR;
}
}
// Check received data
for(i=0; i < I2C.NumOfBytes; i++){
I2C.MsgBufferRx[i] = I2caRegs.I2CDRR;
}
I2C.RdDone=0;
}
}
// Interrupt source = Register Access Ready
// This interrupt is used to determine when the EEPROM address setup portion of the
// read data communication is complete. Since no stop bit is commanded, this flag
// tells us when the message has been sent instead of the SCD flag. If a NACK is
// received, clear the NACK bit and command a stop. Otherwise, move on to the read
// data portion of the communication.
else if(IntSource == I2C_ARDY_ISRC){
if(I2caRegs.I2CSTR.bit.NACK == 1){
I2caRegs.I2CMDR.bit.STP = 1;
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
}
else if(I2C.MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY){
I2C.MsgStatus = I2C_MSGSTAT_RESTART;
}
} // end of register access ready
// Enable future I2C (PIE Group 8) interrupts
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}