Hi
I am programming the I2C module in the loopback mode for TMS320F28035 and I am facing the following problem -
I am trying to write data, to an EEPROM- AT24C32D (slave addr :0XA0/A1) but, after reading back i saw that only the 1st 4 bytes get written successfully and the remaing bytes read default 0xFF. ( i tried with 10 , 32 bytes )
It is in polling mode and RRDY and XRDY are the flags.
Can someone please help me on this ?
Please find the code attached
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>I2C EEPROM(i2c_eeprom)</h1> //! //! This program requires an external I2C EEPROM connected to //! the I2C bus at address 0x50. //! This program will write 1-14 words to EEPROM and read them back. //! The data written and the EEPROM address written to are contained //! in the message structure, \b I2cMsgOut1. The data read back will be //! contained in the message structure \b I2cMsgIn1. //! //! \note This program will only work on kits that have an on-board I2C EEPROM. T //! (e.g. F2803x eZdsp) //! //! \b Watch \b Variables \n //! - I2cMsgIn1 //! - I2cMsgOut1 // //########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $ // $Release Date: March 30, 2013 $ //########################################################################### #include "DSP28x_Project.h" // Device Headerfile and Examples Include File // Note: I2C Macros used in this example can be found in the // DSP2803x_I2C_defines.h file // Prototype statements for functions found within this file. void I2CA_Init(void); Uint16 I2CA_WriteData(struct I2CMSG *msg); Uint16 I2CA_ReadData(struct I2CMSG *msg); __interrupt void i2c_int1a_isr(void); void pass(void); void fail(void); void compare_I2C_RW(void); Uint16 correct=0; #define I2C_SLAVE_ADDR 0x50 #define I2C_SLAVE_ADDR_READ 0x51 //#define I2C_NUMBYTES 2 #define I2C_NUMBYTES 10 #define I2C_EEPROM_HIGH_ADDR 0x00 #define I2C_EEPROM_LOW_ADDR 0x30 // Global variables // Two bytes will be used for the outgoing address, // thus only setup 14 bytes maximum struct I2CMSG I2cMsgOut1={I2C_MSGSTAT_SEND_WITHSTOP, I2C_SLAVE_ADDR, I2C_NUMBYTES, I2C_EEPROM_HIGH_ADDR, I2C_EEPROM_LOW_ADDR, 0x12, // Msg Byte 1 0x34, 0x56, 0x78, 0x06, 0x06, 0x06, 0x06, // Msg Byte 2 0x06, 0x06}; struct I2CMSG I2cMsgIn1={ I2C_MSGSTAT_SEND_NOSTOP, I2C_SLAVE_ADDR, I2C_NUMBYTES, I2C_EEPROM_HIGH_ADDR, I2C_EEPROM_LOW_ADDR}; struct I2CMSG *CurrentMsgPtr; // Used in interrupts Uint16 PassCount; Uint16 FailCount; Uint16 GlobalCount=0; void main(void) { Uint16 Error; Uint16 i; CurrentMsgPtr = &I2cMsgOut1; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file. InitSysCtrl(); // Step 2. Initialize GPIO: // This example function is found in the DSP2803x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Setup only the GP I/O only for I2C functionality InitI2CGpio(); // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts DINT; // Initialize PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the DSP2803x_PieCtrl.c file. InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c. InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. EALLOW; // This is needed to write to EALLOW protected registers // PieVectTable.I2CINT1A = &i2c_int1a_isr; EDIS; // This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this example I2CA_Init(); for (i = 0; i < I2C_MAX_BUFFER_SIZE; i++) { I2cMsgIn1.MsgBuffer[i] = 0x0000; } I2CA_WriteData(&I2cMsgOut1); CurrentMsgPtr = &I2cMsgIn1; I2CA_ReadData(&I2cMsgIn1); compare_I2C_RW(); } // Step 5. User specific code Uint16 I2CA_WriteData(struct I2CMSG *msg) { Uint16 i=0; //I2caRegs.I2CMDR.all = 0x2620;//Start condition, Master transmitter, 7 bit addr, nonrepeat mode // Setup slave address I2caRegs.I2CSAR = msg->SlaveAddress; I2caRegs.I2CMDR.all = 0x2E20;//Start condition, Master transmitter, 7 bit addr, nonrepeat mode I2caRegs.I2CCNT = msg->NumOfBytes+2; I2caRegs.I2CDXR = msg->MemoryHighAddr; while(!(I2caRegs.I2CSTR.bit.XRDY)); I2caRegs.I2CDXR = msg->MemoryLowAddr; while(!(I2caRegs.I2CSTR.bit.XRDY)); for (i=0; i<msg->NumOfBytes; i++) { //while(!(I2caRegs.I2CSTR.bit.XRDY)) I2caRegs.I2CDXR = *(msg->MsgBuffer+i); while(!(I2caRegs.I2CSTR.bit.XRDY)); } // Send start as master transmitter, free running with breakpoint, IRS=1,STP=1,STT=1,NACKMODE=0,MST=1,TRX=1,FREE=1,STB=1 return I2C_SUCCESS; } Uint16 I2CA_ReadData(struct I2CMSG *msg) { Uint16 i=0; I2caRegs.I2CSAR = msg->SlaveAddress; I2caRegs.I2CMDR.all = 0x2620;//Start condition, Master transmitter, 7 bit addr, nonrepeat mode I2caRegs.I2CCNT = 2; I2caRegs.I2CDXR = msg->MemoryHighAddr; // I2caRegs.I2CSTR.bit.XRDY=1; while(!(I2caRegs.I2CSTR.bit.XRDY)); I2caRegs.I2CDXR = msg->MemoryLowAddr; while(!(I2caRegs.I2CSTR.bit.XRDY)); I2caRegs.I2CSAR = msg->SlaveAddress; I2caRegs.I2CMDR.all=0x2C20; I2caRegs.I2CCNT=msg->NumOfBytes; for (i=0; i<msg->NumOfBytes; i++) { ; while(!(I2caRegs.I2CSTR.bit.RRDY)); *(msg->MsgBuffer+i)=I2caRegs.I2CDRR; } return I2C_SUCCESS; } void I2CA_Init(void) { 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 = 0; I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset return; } void compare_I2C_RW() { Uint16 i; //Uint16 correct=0; for(i=0;i<I2C_NUMBYTES;i++) { if(I2cMsgOut1.MsgBuffer[i]==I2cMsgIn1.MsgBuffer[i]) { correct++; } } }