Other Parts Discussed in Thread: PCF8575, TMS320F28069
Dear Sir/Madam,
I am using PCF8575 with TMs320F28069.I want to read the stayus of I/O line of PCF857,.but I am not able to read the PCF8575..I got the data from PCF8575 is 0x4040; and after getting this data my interrupt is halted. I set the I/o line of PCF8575 to 0x0001;I am refering the I2c_eeprom code for interfacing. of PCF8575.
#include"I2C.h"
// Prototype statements for functions found within this file.
int16 ModbusData[MEM_SIZE];
void I2CA_Init(void);
void I2CA_ReadCheck1(Uint8 dido_id);
void I2CA_WriteCheck1(Uint8 dido_id);
Uint16 I2CA_WriteData(struct I2CMSG *msg);
Uint16 I2CA_ReadData(struct I2CMSG *msg);
interrupt void i2c_int1a_isr(void);
struct I2CMSG I2cMsgInOut[8]={
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO1_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO2_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO3_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO4_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO5_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO6_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO7_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_DIDO8_ADDR,
I2C_W_NUMBYTES
},
};// Msg Byte 1
struct I2CMSG I2cMsgIn[8]={
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO1_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO2_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO3_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO4_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO5_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO6_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO7_ADDR,
I2C_W_NUMBYTES
},
{ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_DIDO8_ADDR,
I2C_W_NUMBYTES
},
};// Msg Byte 1
Uint16 IntSource, i;
Uint16 WriteData = 0xF0;
Uint16 ReadData = 0;
Uint16 delay_counter = 50000;
void InitI2CGpio();
volatile Uint16 read_data[2];
// Global variables
// Two bytes will be used for the outgoing address,
// thus only setup 14 bytes maximum
struct I2CMSG *CurrentMsgPtr; // Used in interrupts
void I2CA_Init(void)
{
unsigned char i;
// Initialize I2C
I2caRegs.I2CSAR = I2C_SLAVE_DIDO6_ADDR; // Slave address - EEPROM control code
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: 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 = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
// Clear incoming message buffer
/* for (i = 0; i < 9; i++)
{
I2cMsgInOut[i].MsgBuffer[0] = WriteData;
I2cMsgInOut[i].MsgBuffer[1] = WriteData;
}
*/
CurrentMsgPtr = &I2cMsgIn[5];
// return;
}
void I2CA_WriteCheck1(Uint8 dido_id)
{
Uint16 Error;
// Check the outgoing message to see if it should be sent.
// In this example it is initialized to send with a stop bit.
if(I2cMsgInOut[dido_id].MsgStatus == I2C_MSGSTAT_SEND_WITHSTOP)
{
Error = I2CA_WriteData(&I2cMsgInOut[dido_id]);
ModbusData[9]++;
ModbusData[3] = I2cMsgInOut[dido_id].MsgStatus;
// If communication is correctly initiated, set msg status to busy
// and update CurrentMsgPtr for the interrupt service routine.
// Otherwise, do nothing and try again next loop. Once message is
// initiated, the I2C interrupts will handle the rest. Search for
// i2c_int1a_isr in this file.
if (Error == I2C_SUCCESS)
{
CurrentMsgPtr = &I2cMsgInOut[dido_id];
I2cMsgInOut[dido_id].MsgStatus = I2C_MSGSTAT_WRITE_BUSY;
ModbusData[18]++;
ModbusData[4] = I2cMsgInOut[dido_id].MsgStatus;
}
} // end of write section
ModbusData[5] = I2cMsgInOut[dido_id].SlaveAddress;
ModbusData[8] = I2cMsgInOut[dido_id].MsgStatus;
}
Uint16 I2CA_WriteData(struct 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)
{
// ModbusData[33] = 33;
return I2C_STP_NOT_READY_ERROR;
}
// Setup slave address
I2caRegs.I2CSAR = msg->SlaveAddress;
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
// Setup number of bytes to send
// MsgBuffer + Address
I2caRegs.I2CCNT = msg->NumOfBytes;
// Setup data to send
// I2caRegs.I2CDXR = msg->MemoryHighAddr;
// I2caRegs.I2CDXR = msg->MemoryLowAddr;
// for (i=0; i<msg->NumOfBytes-2; i++)
for (i=0; i<msg->NumOfBytes; i++)
{
I2caRegs.I2CDXR = *(msg->MsgBuffer+i);
}
// Send start as master transmitter
I2caRegs.I2CMDR.all = 0x6E20;
// ModbusData[35] = 35;
return I2C_SUCCESS;
}
void I2CA_ReadCheck1(Uint8 dido_id)
{
ModbusData[5] = I2cMsgIn[dido_id].SlaveAddress;
ModbusData[8] = I2cMsgIn[dido_id].MsgStatus;
if(I2cMsgIn[dido_id].MsgStatus == I2C_MSGSTAT_SEND_NOSTOP)
{
// EEPROM address setup portion
while(I2CA_ReadData(&I2cMsgIn[dido_id]) != I2C_SUCCESS)
{
// Maybe setup an attempt counter to break an infinite while
// loop. The EEPROM will send back a NACK while it is performing
// a write operation. Even though the write communique is
// complete at this point, the EEPROM could still be busy
// programming the data. Therefore, multiple attempts are
// necessary.
}
// Update current message pointer and message status
CurrentMsgPtr = &I2cMsgIn[dido_id];
I2cMsgIn[dido_id].MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;
}
// Once message has progressed past setting up the internal address
// of the EEPROM, send a restart to read the data bytes from the
// EEPROM. Complete the communique with a stop bit. MsgStatus is
// updated in the interrupt service routine.
else if(I2cMsgIn[dido_id].MsgStatus == I2C_MSGSTAT_RESTART)
{
// Read data portion
ModbusData[34] = 34;
while(I2CA_ReadData(&I2cMsgIn[dido_id]) != I2C_SUCCESS)
{
// Maybe setup an attempt counter to break an infinite while loop
} // Update current message pointer and message status
ModbusData[34] = dido_id;
CurrentMsgPtr = &I2cMsgIn[dido_id];
I2cMsgIn[dido_id].MsgStatus = I2C_MSGSTAT_READ_BUSY;
}
if (I2cMsgIn[dido_id].MsgStatus == I2C_MSGSTAT_INACTIVE)
{
ModbusData[35]++;
I2cMsgIn[dido_id].MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
ReadData = I2cMsgIn[dido_id].MsgBuffer[0];
ReadData |= (I2cMsgIn[dido_id].MsgBuffer[1] << 8 );
ModbusData[20] = ReadData;
ModbusData[37] = I2cMsgIn[dido_id].MsgStatus;
}
ModbusData[5] = I2cMsgIn[dido_id].SlaveAddress;
}
Uint16 I2CA_ReadData(struct 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;
}
I2caRegs.I2CSAR = (msg->SlaveAddress) ;
if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP)
{
ModbusData[36]++;
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR = 0xFF;//msg->MemoryHighAddr;
I2caRegs.I2CDXR = 0xFF;//msg->MemoryHighAddr;
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.I2CMDR.all = 0x2E20; // Send restart as master receiver
}
ModbusData[15]++;
return I2C_SUCCESS;
}
interrupt void i2c_int1a_isr(void) // I2C-A
{
ModbusData[0]++;
// Read interrupt source
IntSource = I2caRegs.I2CISRC.all;
// Interrupt source = stop condition detected
if(IntSource == I2C_SCD_ISRC)
{
// If completed message was writing data, reset msg to inactive state
if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_WRITE_BUSY)
{
CurrentMsgPtr->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(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
}
// If completed message was reading EEPROM data, reset msg to inactive state
// and read data from FIFO.
else if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_READ_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
ModbusData[19]++;
for(i=0; i < 2; i++)
{
CurrentMsgPtr->MsgBuffer[i] = I2caRegs.I2CDRR;
ModbusData[10+i] = I2caRegs.I2CDRR;
}
}
}
} // end of stop condition detected
// 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)
{
ModbusData[39] = (CurrentMsgPtr->MsgStatus);
ModbusData[38]++;
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CMDR.bit.STP = 1;
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
}
if((CurrentMsgPtr->MsgStatus) == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
(CurrentMsgPtr->MsgStatus) = I2C_MSGSTAT_RESTART;
}
} // end of register access ready
else
{
// Generate some error due to invalid interrupt source
asm(" ESTOP0");
}
// Enable future I2C (PIE Group 8) interrupts
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}
//===========================================================================
// No more.
//===========================================================================
Please find the attached file for your reference.
Please help me its urgent.
