CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Slowing down the i2c Bus

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
leem



Joined: 16 Jan 2008
Posts: 7

View user's profile Send private message

Slowing down the i2c Bus
PostPosted: Fri Nov 20, 2009 3:16 pm     Reply with quote

Hey Everyone,
Having a slight problem with a 18f14k50 chip and i2c bus.

I am using complier ver 4.099. I am trying to use the hardware i2c pins on the micro to talk to a chip that specifically says it can only communicate at a speed of no more then 50khz. I have tried numerous ways to set the bus speed. I tried

Code:
#include <18F14K50.h>
#use delay (clock=20MHZ)

#define I2C_SCL PIN_B6
#define I2C_SDA PIN_B4
#use I2C(master, scl=I2C_SCL, sda=I2C_SDA, slow=45000, force_sw, stream=AUTHCHIP)


but still doesn't work. I measured clock speed is around 365khz then jumps up to 400khz when trying to talk to the device. Doesn't seem to matter if I specify slow, fast, fast=, slow=, it still runs the speeds listed above. I am pretty new to the i2c but I am thinking there is some other register I have to set. Can someone point me into the right direction on where I need to look to set it.

Thanks

-Lee
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 3:53 pm     Reply with quote

I took your code and made it into a test program. The CCS manual
doesn't say that different speed settings for the "Slow" parameter are
supported. They might actually be supported, but it's best to just
follow what the manual says. So I changed "Slow" to "Fast" in your code.

I then compiled the program and looked at the .LST file code starting
at address 0004. This is the #use i2c() library code.

The delays for the high and low period of the SCL clock are 10 us each.
The remaining instructions take about 3 us more, giving 23 us total,
which gives a clock speed of about 43.5 KHz. So, I think it should be
working. Are you looking at the SCL pin with your oscilloscope ?
Code:

0004:  MOVLW  08    // Send 8 bits
0006:  MOVWF  @01

0008:  MOVLW  10      // 10 usec delay (50 clocks / 5 clks per usec)
000A:  MOVWF  @00
000C:  DECFSZ @00,F
000E:  BRA    000C

0010:  BCF    LATB.6    // SCL = 0
0012:  BCF    TRISB.6

0014:  MOVLW  10        // 10 usec delay
0016:  MOVWF  @00
0018:  DECFSZ @00,F
001A:  BRA    0018

001C:  RLCF   06,F     // Rotate data byte
001E:  BCF    LATB.4   // Send 0 or 1 based on data bit
0020:  BTFSC  STATUS.C
0022:  BSF    TRISB.4
0024:  BTFSS  STATUS.C
0026:  BCF    TRISB.4

0028:  BSF    TRISB.6      // SCL = 1  (float high)
002A:  BTFSS  PORTB.6   // Check for clock stretching
002C:  BRA    002A

002E:  DECFSZ @01,F    // Decrement bit count
0030:  BRA    0008        // Loop until all 8 bits are sent




Code:

#include <18F14K50.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay (clock=20MHZ)
#define I2C_SCL PIN_B6
#define I2C_SDA PIN_B4
#use I2C(master, scl=I2C_SCL, sda=I2C_SDA, FAST=45000, force_sw, stream=AUTHCHIP)

//======================================
int8  main ()
{

while(1)
  {
   i2c_write(AUTHCHIP, 0xF0);
   delay_us(50);
  }

while(1);
}
leem



Joined: 16 Jan 2008
Posts: 7

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 4:21 pm     Reply with quote

I took your code and tried it and low and behold it was actually clocking at 32.33 khz. I have a meter that can measure frequency so yes I am measuring the SCL line clock speed.

Apparently I have some other setting in my code that is affecting the clocking and I will have to look for it.

Playing around with your code sample, I decided to try changing it to force_hw since it has it built in but that makes to clock at 368Khz. So I am guessing that need to do it via software as opposed to hardware.

-Lee
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 5:13 pm     Reply with quote

Force_hw is working as well, down to about 40 kHz (fast =40000) with a 20 MHz crystal.
leem



Joined: 16 Jan 2008
Posts: 7

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 6:04 pm     Reply with quote

Can you give me the code you used exactly to get that. I just tried pcm's code and changed it FAST=40000 and force_hw and I still am getting over 300Khz clocking on the SCL line.


-Lee
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 6:25 pm     Reply with quote

I changed my test program to "Force_hw" and compiled it with vs. 4.099.
There appears to be a bug in the start-up code. This is the init code that
CCS puts at the beginning of main(). It sets up the hardware i2c baud
rate register (to 0x6F), but then it clobbers it later by setting it to 0xFF.
Quote:

0022: CLRF TBLPTRU
0024: BCF RCON.IPEN
0026: CLRF FSR0H
0028: CLRF FSR0L
002A: BSF TRISB.6
002C: BSF TRISB.4

002E: MOVLW 6F
0030: MOVWF SSPADD

0032: MOVLW 29
0034: MOVWF SSPCON1
0036: BSF SSPSTAT.SMP
0038: BCF SSPSTAT.CKE

003A: MOVLW FF
003C: MOVWF SSPADD

003E: MOVLW 28
0040: MOVWF SSPCON1
0042: MOVLW 00
0044: MOVWF ANSEL
0046: BCF ADCON1.NVCFG0
0048: BCF ADCON1.NVCFG1
004A: BCF ADCON1.PVCFG0
004C: BCF ADCON1.PVCFG1
004E: MOVWF ANSELH
0050: CLRF FB4


However, there is a work-around. You can manually set the i2c baud
rate (in Force_hw mode) by calling the i2c_speed() function at the
start of main(). That will reset the baud rate to the correct value.
This occurs after the start-up code has been executed, so it fixes the
problem with the incorrect baud rate.
Code:

.......... i2c_speed(AUTHCHIP, 45000);
0052:  MOVLW  6F
0054:  MOVWF  SSPADD
0056:  MOVLW  29
0058:  MOVWF  SSPCON1
005A:  BSF    SSPSTAT.SMP
leem



Joined: 16 Jan 2008
Posts: 7

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 7:31 pm     Reply with quote

So from what you said It should be this

Code:
#include <18F14K50.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay (clock=20MHZ)
#define I2C_SCL PIN_B6
#define I2C_SDA PIN_B4
#use I2C(master, scl=I2C_SCL, sda=I2C_SDA, FAST=45000, force_hw, stream=AUTHCHIP)

//======================================
int8  main ()
{
   i2c_speed(AUTHCHIP, 45000);
while(1)
  {
   i2c_write(AUTHCHIP, 0xF0);
   delay_us(50);
  }

while(1);
}


Tried it at still clocking at 368khz for me

-Lee
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 8:01 pm     Reply with quote

Well, I don't have the hardware. All I can do is look at the .LST file.
leem



Joined: 16 Jan 2008
Posts: 7

View user's profile Send private message

PostPosted: Fri Nov 20, 2009 9:18 pm     Reply with quote

That cool, figured you didn't. Just reporting what I am experiencing. I appreciate the help.

-Lee
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Nov 21, 2009 4:20 am     Reply with quote

I wonder, how measure the I2C clock frequency with a frequency meter, because it comes in short bursts.
Did you ever see the fast clocking with an oscilloscope?

According to the datasheet, the wrong SSPADD setting of 0xff would give a low rather than a high frequency.
electron_plumber



Joined: 18 Jun 2008
Posts: 2
Location: Washington, USA

View user's profile Send private message

SSPADD rewrite...
PostPosted: Fri Jul 09, 2010 1:33 am     Reply with quote

I have a very similar issue - hardware I2C running WAY slow. (The direction you would expect.) I too found that SSPADD was getting clobbered, so I manually reset it by directly writing to SSPADD. However, some values worked, while others just locked it up (i.e. the port stopped sending data entirely).

I will try using i2c_speed tomorrow, and see if that helps. It hadn't occurred to me that the other registers might need to be reloaded as well...

I am using the latest version of the compiler, and I'm a bit surprised that this hasn't been fixed yet...

Anyhow, glad to see I wasn't the only one with this problem...
electron_plumber



Joined: 18 Jun 2008
Posts: 2
Location: Washington, USA

View user's profile Send private message

i2c_speed(400000) doesn't work either!
PostPosted: Fri Jul 09, 2010 1:22 pm     Reply with quote

i2c_speed(400000) did not solve my problem! Looking at the listing file (including the one above), it puts 0x29 into SSPCON1 which is a disallowed value (at least on the PIC18F14K50 I am using...).

I manually went in and set SSPADD=0x0c (~400kHz on a 20MHz clock) and SSPCON1=0x28 (the 8 coresponding to master mode). That seems to have solved my problem!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 09, 2010 4:02 pm     Reply with quote

I tested your code with vs. 4.109 and found the same problems.
You should report these bugs to CCS support. Show them the
.LST file in your email, and point out where it's programming
the registers incorrectly.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group