cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
sachinm1984
Visitor
Visitor
20,083 Views
Registered: ‎03-24-2010

I2C IP with MicroBlaze

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 

Tags (2)
0 Kudos
Reply
9 Replies
secureasm
Voyager
Voyager
20,077 Views
Registered: ‎05-09-2008

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 Variable

unsigned int count;
unsigned char * ptr;

// Setup destination pointer

ptr = destination;

// Read data on I2C bus

count = XIic_Recv(XPAR_I2C_BASEADDR, (device >> 1), ptr, len, XIIC_STOP);

// Test reading

if(count != len)
{
// No more data

count = -1;
}
else
{
// Ok

count = 0;
}

// Exit

return 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 bus

count = 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

Message Edited by secureasm on 03-31-2010 12:20 AM
0 Kudos
Reply
sachinm1984
Visitor
Visitor
20,054 Views
Registered: ‎03-24-2010

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.

 

 

0 Kudos
Reply
secureasm
Voyager
Voyager
20,049 Views
Registered: ‎05-09-2008

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
0 Kudos
Reply
sachinm1984
Visitor
Visitor
20,038 Views
Registered: ‎03-24-2010

I had the pins on pullup. Acually, before reading, I was using MasterSend for writing with Repeated Start option which was not probably not giving a Stop bit at the end causing the problem when I read. When I removed the Repeated Start option, the read function started working properly. Thanks for your help.
0 Kudos
Reply
bassman59
Historian
Historian
19,986 Views
Registered: ‎02-25-2008


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.

----------------------------Yes, I do this for a living.
0 Kudos
Reply
secureasm
Voyager
Voyager
19,954 Views
Registered: ‎05-09-2008

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

0 Kudos
Reply
bassman59
Historian
Historian
19,945 Views
Registered: ‎02-25-2008


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.

 

----------------------------Yes, I do this for a living.
0 Kudos
Reply
Anonymous
Not applicable
19,633 Views

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

0 Kudos
Reply
noor811x
Visitor
Visitor
17,715 Views
Registered: ‎09-20-2008

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

0 Kudos
Reply