This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Does any one know if there exists a synchronous read/write (with out using ISR) example for C2000 ? The i2c_eeprom example is somewhat complex.
Thanks,
Prakash
I have the same issue...if somebody can provide simple I2C write/read code without interrups would be great.
//##################### I2C_Write #################################################################################
// Function Name: void I2C_Write
// Return Type: void
// Arguments: Uint16 Slave_address, Uint16 Start_address, Uint16 No_of_databytes, Uint16 Write_Array[]
// Description: I2C Write Driver. Pass Slave Address, Write location, No of databytes and the array with data.
//#################################################################################################################
void I2C_Write(Uint16 Slave_address, Uint16 Start_address, Uint16 No_of_databytes, Uint16 Write_Array[])
{
Uint16 i = 0;
I2caRegs.I2CSAR = Slave_address;
while(I2caRegs.I2CMDR.bit.STP != 0);
// Start bit, write mode, Higher 16 address bits, Master, Repeat mode.
I2caRegs.I2CMDR.bit.TRX = TRANSMIT_MESSAGE;
//######## Only for EEPROM #########################//
if(Slave_address == EEPROM_24LC256_ADDRESS)
{
I2caRegs.I2CDXR = (Start_address)>>8;
}
//##################################################//
I2caRegs.I2CMDR.all = 0x26A0;
//(Lower 16) address bits
while(I2caRegs.I2CSTR.bit.ARDY != 1);
if (I2caRegs.I2CSTR.bit.ARDY == 1)
{
I2caRegs.I2CDXR = Start_address;
}
// Data Bytes to be transmitted
while(i < No_of_databytes)
{
while(I2caRegs.I2CSTR.bit.ARDY != 1);
// DSP28x_usDelay(5000);
if (I2caRegs.I2CSTR.bit.ARDY == 1)
{
I2caRegs.I2CDXR = Write_Array[i++]; // Lower 16 address bits
}
}
while (I2caRegs.I2CSTR.bit.NACK == 1) // Clear if NACK received
{
I2caRegs.I2CSTR.bit.NACK = 1;
}
I2caRegs.I2CMDR.all = 0x0EA0;
while(I2caRegs.I2CSTR.bit.SCD != 1);
I2caRegs.I2CSTR.bit.SCD = 1; // Clear stop condition
}
//##################### I2C_Read ##################################################################################
// Function Name: void I2C_Read
// Return Type: void
// Arguments: Uint16 Slave_address, Uint16 Start_address, Uint16 No_of_databytes, Uint16 Read_Array[]
// Description: I2C Read Driver. Pass Slave Address, Write location, No of databytes, Array where received
// will be copied.
//#################################################################################################################
void I2C_Read(Uint16 Slave_address, Uint16 Start_address, Uint16 No_of_databytes, Uint16 Read_Array[])
{
Uint16 i = 0;
I2caRegs.I2CSAR = Slave_address;
I2caRegs.I2CCNT = No_of_databytes; // When operating in non repeat mode, this value will determine how many bytes to receive/send.
Uint16 *Temp_Pointer;
Temp_Pointer = Read_Array;
while(I2caRegs.I2CMDR.bit.STP != 0); // Detect a stop bit
// Start bit, write mode, Higher 16 address bits, Master, Non Repeat mode.
I2caRegs.I2CMDR.bit.TRX = 1;
//######## Only for EEPROM #########################//
if(Slave_address == EEPROM_24LC256_ADDRESS)
{
I2caRegs.I2CDXR = (Start_address)>>8;
}
//##################################################//
I2caRegs.I2CMDR.all = 0x26A0;
while(I2caRegs.I2CSTR.bit.ARDY != 1);
if (I2caRegs.I2CSTR.bit.ARDY == 1)
{
I2caRegs.I2CDXR = Start_address; // (Lower 16) address bits
}
while(I2caRegs.I2CSTR.bit.ARDY != 1);
// Put a stop bit. Because we need to change to non repeat mode.
I2caRegs.I2CMDR.bit.STP = 1;
while(I2caRegs.I2CMDR.bit.STP != 0); // Detect a stop bit
I2caRegs.I2CMDR.all = 0x2C20;
while(i < No_of_databytes)
{
while(I2caRegs.I2CSTR.bit.RRDY != 1);
*Temp_Pointer++ = I2caRegs.I2CDRR;
i++;
}
}
These functions are tested with 4 different I2C slaves (2 display drivers, Temp sensor and EEPROM). Works 100%.
Note: #define EEPROM_24LC256_ADDRESS 0x50
Hi Vivek, Thanks a lot for sharing the code. This is what exactly I was looking for. It really saves a lot of time.
--Prakash
no problems,
test the code and see.. let me know if you face any problems. this one goes inside a critical project.. needs to be tested as much as possible.
please give me your feedback guys
Vivek,
It hangs in the following line of I2C_Write.
while (I2caRegs.I2CSTR.bit.ARDY != 1);
Can you please your i2c init function ? Below is what I use.
void i2c_init() {
InitI2CGpio();
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.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended
}
Thanks,
Prakash
Hi Prakash,
Find code below for I2C initialisation with a note on how to configure the I2C module for a specific baud rate. I'm using TMS320F2808 with 100M Sysclkout
//################################### I2C Bus Baud Rate Settings ###############################################
// Sysclkout is input to the I2C module. We operate at 100MHz sysclkout.
//
// I2C Baud Rate = I2C_Input_Clock_Frequency/{ (IPSC + 1)[(ICCL + d) + (ICCH + d)] }
//
// IPSC vs d Our Settings:
// IPSC d IPSC: 9 ==> d: 5
// 0 7 ICCL: 20
// 1 6 ICCH: 10
// > 1 5
//
// Baud Rate set = 100M/{(9+1)[(20+5)+(10+5)]} = 250Kbps
//#################################################################################################################
//##################### Initialize I2C ############################################################################
// Function Name: InitI2C()
// Return Type: void
// Arguments: void
// Description: Initializes the I2C peripheral. Operates at 250kbps. For Baud Rate setting related information
// see I2CApp.c
//#################################################################################################################
static void InitI2C(void)
{
I2caRegs.I2CSAR = 0x00 ; //Dummy
I2caRegs.I2CMDR.bit.IRS = 0; // Hold in reset
I2caRegs.I2CPSC.all = 9; // d value becomes 5.
I2caRegs.I2CCLKL = 20;
I2caRegs.I2CCLKH = 10;
I2caRegs.I2CIER.all = 0x00;
I2caRegs.I2CMDR.bit.MST = 1; // Master
I2caRegs.I2CMDR.bit.XA = 0;
I2caRegs.I2CMDR.bit.RM = 1;
I2caRegs.I2CMDR.bit.BC = 0;
I2caRegs.I2CMDR.bit.STP = 0;
I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset
}
Sir,
I tried to implement the same code for the communication but my code hangs at the read routine."while(I2caRegs.I2CSTR.bit.RRDY != 1);".
It never comes out of this routine.Any suggetions..
Regards
Manju R
Thank you for the code you have given in the site...
it works fine with my app too...
Hi Manju,
I had exactly the same problem before.
In my case, the reason was I used FIFO mode. If you are running on FIFO mode, you need to check RXFFINT instead of RRDY.
The line should be replaced with "while(I2caRegs.I2CFFRX.bit.RXFFINT != 1)"
Hello,
I used the above code to read / Write on 24AA256 by using PAGE WRITE and PAGE READ protocol. In this case, PAGE length is given in the datasheet at 64 bytes per page. So, It seems to write (I see the datagram on scope and calculate the time duration) but when i tried to read back what I have written I read only one time and then Bus line became low (both) such as when it wait an ACK or STP bit.
Do you have any experience of it ?
Thanks in adance
Ol