View previous topic :: View next topic |
Author |
Message |
arrow
Joined: 17 May 2005 Posts: 213
|
i2c speed- too slow? |
Posted: Fri Jun 24, 2005 4:58 am |
|
|
Hi
I am really battling with the i2c and writting to an external EEPROM.
I have the following subroutine, which actually does work, however it seems too slow:
void pageWrite_ext_eeprom(long int address, byte mask){
int ik;
//***Line #1
START:
i2c_start();
if(i2c_write(0xa0 | mask)!=0) //Device must ACKNOWLEDGE
goto START;
i2c_write(address>>8); //High Byte of Address
i2c_write(address&0X00FF); //Low Byte of Address
//***Line #2
for(ik=0;ik<32;ik++){ //Write Page to EEPROM
i2c_write(dat[ik]);
}
//***Line #3
i2c_stop();
}
At the top of the file I have:
#use i2c(master,sda=EEPROM_SDA, scl=EEPROM_SCL)
I have 2 10k pull up resistors on the SDA and SCL lines.
The time it takes for a PIC16LF873 to go from Line 1 to Line 2 = 726 ticks
The time it takes to go from Line #2 to Line #3 = 7827ticks
It seems very very slow to me- can someone please tell me if these times are reasonable (I am using a 4MHz Xstal).
and If not, then what I am doing wrong?
Thank you in advance for your help.
arrow |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Jun 24, 2005 5:11 am |
|
|
I have not used I2C routines of CCS however I don't see where you have set the clock rate for the I2C bus.
Also don't forget that when you issue the i2c_stop() the EEPROM will be busy for 5ms. If you attempt another write in this time then you will be locked in your goto loop.
Why did you use goto instead of a while loop?
Code: |
while(i2c_write(0xa0 | mask)!=0) //Device must ACKNOWLEDGE
; |
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Fri Jun 24, 2005 5:15 am |
|
|
Hi asmallri
I dont know how to set the clock in i2c. My version of CCS seesm to set the clock speed of the i2c automatically.
Still it seems rather a long time to write 32 data points?
arrow |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Jun 24, 2005 5:19 am |
|
|
DO you have a Code: | #use delay(clock=....) | statement? _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Fri Jun 24, 2005 5:23 am |
|
|
Hi
Yes i have the line:
#use delay(clock=4000000)
at the top of the file.
arrow |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Jun 24, 2005 5:34 am |
|
|
If the I2C clock is running at 100K (10 tick per edge) then these numbers look realistic. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Fri Jun 24, 2005 5:38 am |
|
|
Hi
Please can you show me rough calculations on how transfering 32bytes (excluding address writting) should take approximatley 7.8ms (7800 ticks on a 4MHz Xstal)?
Thank you
arrow |
|
|
Ttelmah Guest
|
|
Posted: Fri Jun 24, 2005 5:43 am |
|
|
Have you tried adding 'FAST'?.
What is your compiler version?. Unfrtunately some versions are better than others at calculating the timing values.
How long are your I2C lines, what is the likely capacitance?. 10KR, is rather high. It is pushing the maximum resistor value for 5v I2C. The minimum value for this resistor (assuming you are not using any series resistors in the bus), is about 2KR for a 5v bus. Assuming your bus has a relatively low capacitance (two inputs, and a short track run), then it will be OK, but I'd suggest going lower, especially if you want to push higher switching rates. 4K7, is a more 'common' general use value.
What is a 'tick'?. Is this a processor clock cycle, or a crystal clock cycle?. You need to specify which you are using.
The absolute 'fastest', that could be achieved using 100K I2C, with no 'hold' from the chip, is around 3600 processor cycles.
You are aware that the page size for the 24LC256, which was mentioned in another post, is 64bytes, not 32.
Best Wishes |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Fri Jun 24, 2005 5:59 am |
|
|
Hi Ttelmah
Yes I have tried adding "FAST"-- that did nothing visible.
Compiler version is 2.686-- ie very old.
I use "tick" = XStal clock cycle/4. So in my case its 4MHz/4 => 1us
I am running off a 3.3V power supply using a 16LF873 chip.
I have used 2k ohm resistors- that did nothing visible.
Lines are very short in my case.
The way I see it is:
100khz gives 10us per i2c cycle
to write 32 bytes of data: 32*9*10us = 1980us or 1.98ms
I am getting 7.8ms or about 4 times longer.
Yes I am aware that the page size for the 256 is 64bytes. The problem with using 64byte page in my code is that i get mysterious data comming into the array. 32bytes only produces 1 corrupt data byte. That bad byte is due to the long time in the writting cycle.
If you could help me improve the speed of the i2c i would greately appreciate it.
All the best
arrow |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Jun 24, 2005 6:15 am |
|
|
Don't forget to take the for loop code into account.
You have not used FORCE_HW in the #use statement so the software driver is used with additional instructions are used for setting and clearing bits and for changing I/O direction.
At 1us clock period you may easily be spending more than this time processing the for loop. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Jun 24, 2005 6:41 am |
|
|
How about looking at the signals with a scope to see what is going on
Also, do you have any interrupts? If any interrupts are occuring then your routines will appear longer than they actually are. |
|
|
Ttelmah Guest
|
|
Posted: Fri Jun 24, 2005 9:24 am |
|
|
First thing, writing a byte takes more than even 9 I2C clock times. The minimum time for the ack at the end of each byte, is one clock time, but generally most chips do stretch this a little, so 10 clock times is more likely.
Then the I2C write code, has to wait for the byte to complete, before sending the next byte. Add at least six or seven processor cycles for this. Similarly the loop will involve perhaps another ten cycles.
Your compiler is very old, look at the listing file, and check what value is actually being sent to the I2C baud rate generator. I'd expect it to be setting the rate to perhaps 11, giving a clock of perhaps 83KHz. 100K, is a 'max' spec for the original I2C bus, and the compiler tends to err slightly on the safe side when setting the value.
As others have said, force hardware use as well.
The lower resistors will help if you push the clock rate up, but at <100K, 10KR should be fine.
Best Wishes |
|
|
|