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.