03-30-2010 09:19 PM
Hello,
I am using the IIC IP to write and read the configuration bytes from a PLL device CY22394. I am able to write to the PLL using XIic_MasterSend function. To read from the PLL device, I have to first send the address in the write mode and then read the bytes in the read mode.
- The repeated_start example given alongwith the IP uses XIic_MasterRecv function but this function itself does not send the address from which to read the bytes. So the code given in the IP cannot be used directly for the PLL. So I tried using the XIic_MasterSend function to send the address byte in write mode before I use XIic_MasterRecv function. But this did not work.
- So I checked out the low_level_EEPROM example. In this example in the EepromReadByte function, first the address byte is sent using the XIic_Send function and then bytes are read using the XIic_Recv function. But I am still not getting any result.
In both cases, the array used to read gets filled with all 0s. If anybody has used this IP in similar applications, please help me.
Regards,
Sachin
03-31-2010 12:19 AM - edited 03-31-2010 12:20 AM
Hi sachinm1984,
I use I2C Core for setup EEprom, STV0362, STV0299, STV900 and many other device. Rember to set SCL/SDA width of glitches using this formula :
WIDTH = 100 nS / ( 1 / CLOCK_HZ )
Ex:
CLOCK_HZ = 64000000
WIDTH = 100 nS / (1 / 64000000 )
= 100 nS / 15.625 nS
= 6.4 -> 7
For I2C IPcore i use this funtion, which work very well :
Reading I2C:
// ************************************************************************************
// * *
// * ReadI2CBuffer *
// * *
// * Reading data on I2C bus *
// * *
// * Parameter : (unsigned char) Device address (true address no right rotate 8 bits) *
// * (unsigned char) Address on device *
// * (void *) Destination data buffer *
// * (int) Len of data buffer *
// * *
// * Return : 0 = OK / -1 = Error *
// * *
// ************************************************************************************
int ReadI2CBuffer(unsigned char device, void * destination, int len)
{
// Local Variableunsigned int count;
unsigned char * ptr;
// Setup destination pointerptr = destination;
// Read data on I2C buscount = XIic_Recv(XPAR_I2C_BASEADDR, (device >> 1), ptr, len, XIIC_STOP);
// Test readingif(count != len)
{
// No more datacount = -1;
}
else
{
// Okcount = 0;
}
// Exitreturn count;
}
Wrintig I2C:
// ************************************************************************************
// * *
// * WriteI2CBuffer *
// * *
// * Wrinting data on I2C bus *
// * *
// * Parameter : (unsigned char) Device address (true address no right rotate 8 bits) *
// * (unsigned char) Address on device *
// * (void *) Source data buffer *
// * (int) Len of data buffer *
// * *
// * Return : 0 = OK / -1 = Error *
// * *
// ************************************************************************************
int WriteI2CBuffer(unsigned char device, void * source, int len)
{
// Local Variable
unsigned int count;
unsigned char * ptr;
// Setup source pointer
ptr = source;
// Write data on I2C buscount = XIic_Send(XPAR_I2C_BASEADDR, (device >> 1), ptr, len, XIIC_STOP);
// Test writing
if(count != len)
{
// No more data
count = -1;
}
else
{
// OK
count = 0;
}
// Exit
return count;
}
secureasm
04-01-2010 01:04 AM
Hi secureasm,
Thanks for sharing your code. I have made the changes to the SCL, SDA glitches and have given control from UART to write and read with seperate functions for them. It seems to work. But for some reason, after writing, the first two times the read data is not correct. But the third time, I get the correct data. I wonder why this is happening.
04-01-2010 05:48 AM - edited 04-01-2010 05:49 AM
Hi sachinm1984,
> Thanks for sharing your code. I have made the changes to the SCL, SDA glitches and have given control from UART to write and
> read with seperate functions for them. It seems to work.
Well ...
> But for some reason, after writing, the first two times the read data is not correct. But the third time, I get the correct data. I wonder
> why this is happening.
You have place PULLUP on I2C lines ?
Try this on your .ucf file:
##
## Module I2C constraints
##
Net fpga_0_I2C_SCL_pin LOC = xxx; # SCL
Net fpga_0_I2C_SCL_pin IOSTANDARD = LVCMOS33;
Net fpga_0_I2C_SCL_pin SLEW = SLOW;
Net fpga_0_I2C_SCL_pin DRIVE = 2;
Net fpga_0_I2C_SCL_pin PULLUP;
Net fpga_0_I2C_SDA_pin LOC = xxx; # SDA
Net fpga_0_I2C_SDA_pin IOSTANDARD = LVCMOS33;
Net fpga_0_I2C_SDA_pin SLEW = SLOW;
Net fpga_0_I2C_SDA_pin DRIVE = 2;
Net fpga_0_I2C_SDA_pin PULLUP;
secureasm
04-02-2010 04:37 AM
04-09-2010 04:15 PM
secureasm wrote:Hi sachinm1984,
> Thanks for sharing your code. I have made the changes to the SCL, SDA glitches and have given control from UART to write and
> read with seperate functions for them. It seems to work.
Well ...
> But for some reason, after writing, the first two times the read data is not correct. But the third time, I get the correct data. I wonder
> why this is happening.
You have place PULLUP on I2C lines ?
Try this on your .ucf file:
##
## Module I2C constraints
##
Net fpga_0_I2C_SCL_pin LOC = xxx; # SCL
Net fpga_0_I2C_SCL_pin IOSTANDARD = LVCMOS33;
Net fpga_0_I2C_SCL_pin SLEW = SLOW;
Net fpga_0_I2C_SCL_pin DRIVE = 2;
Net fpga_0_I2C_SCL_pin PULLUP;
Net fpga_0_I2C_SDA_pin LOC = xxx; # SDA
Net fpga_0_I2C_SDA_pin IOSTANDARD = LVCMOS33;
Net fpga_0_I2C_SDA_pin SLEW = SLOW;
Net fpga_0_I2C_SDA_pin DRIVE = 2;
Net fpga_0_I2C_SDA_pin PULLUP;
secureasm
Message Edited by secureasm on 04-01-2010 05:49 AM
Internal FPGA pullups are NOT sufficient for I2C. You need a stronger external pullup.
04-13-2010 12:02 AM
Hi bassman59,
> Internal FPGA pullups are NOT sufficient for I2C. You need a stronger external pullup.
Why internal FPGA pullups are NOT sufficient for I2C ?
secureasm
04-13-2010 10:11 AM
secureasm wrote:Hi bassman59,
> Internal FPGA pullups are NOT sufficient for I2C. You need a stronger external pullup.
Why internal FPGA pullups are NOT sufficient for I2C ?
secureasm
Because the I2C spec calls for 2k resistors to a 3.3V rail and the FPGA internal pullups are easily an order of magnitude higher resistance. This limits the speed at which the bus can run.
05-18-2010 07:08 AM
Hello ,
When using the XIic_send function for sending 5 bytes of data, the slave address is indeed transmitted but the slave device ,which is the chip, doesn't reply with an acknowledge during the 9th clock of sclk( there is '1' logic instead of '0' logic). I tried many ways to overcome this problem from configuring the XPAR IIC INTERFACE via EDK ( changeing the width of glitches for sda and scl as one from this forum adviced ) to adding pullups in the ucf constraint file and even adding external pullups. No matter what, I still can't see that the slave device answers with an acknowledge.
I'am really stuck in my project and every help can be welcome excpesially because the project needs to be done no more then a couple of months!
Thank you very much,
Looking forward for your reply, Haz88
I have attached my main c source file and a look from a logic analyzer when using XIic_send function
02-28-2011 04:45 PM - edited 02-28-2011 05:06 PM
Thanks to Bassman for that info on the I2C pin settings in UCF file, that helped me get the XIIC working for the first time!! Now onto controlling an Aptina CMOS Image sensor.. :D