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

#use i2c not changing pins with 18f4520

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



Joined: 03 Sep 2012
Posts: 4

View user's profile Send private message

#use i2c not changing pins with 18f4520
PostPosted: Mon Sep 03, 2012 3:48 pm     Reply with quote

Hi,
I want to be able to change the i2c pins with #use i2c for different hardware revisions.

This simple code does not work:
Code:

   //UseFastI2c defaults to FALSE
   temp=read_eeprom(FastI2cInstalledAddr);
   if (temp!=1){

      UseFastI2c=FALSE;
      write_eeprom(FastI2cInstalledAddr,0);
      #use i2c(master, sda=PIN_C4, scl=PIN_D3))
      output_float(PIN_D3);

   }else{

                      UseFastI2c=TRUE;
      #use i2c(master, sda=PIN_C4, scl=PIN_C3))
      output_float(PIN_C3);
      MinorVersion|=16;

   }

As you can see, sda stays on PIN_C4, but scl changes between PIN_C3 and PIN_D3; depending upon the state of the internal eeprom read. I have breakpointed the if statement and verified reading eeprom does execute both cases, but an o-scope shows scl stays on PIN_D3 regardless.

I'm using compiler version 4.3.0.275 and am using a 18F4520.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 4:21 pm     Reply with quote

Quote:
This simple code does not work.

#use i2c statements do not globally change the mode of the runtime code.
Each statement generates a new instance of the CCS i2c library code
and all i2c functions that occur after the current #use i2c statement
will use the parameters in that statement. That's why your code doesn't work.

You can do what you want by using "streams". See the CCS manual in
the #use i2c section. Look at the 'streams' parameter. See this thread
for an example:
http://www.ccsinfo.com/forum/viewtopic.php?t=43577

Quote:
I'm using compiler version 4.3.0.275

That's not your version. Your version is 4.101. It's given at the top of
the .LST file, which is in your project directory after a successful
compilation.
stephanhwolf



Joined: 03 Sep 2012
Posts: 4

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 5:17 pm     Reply with quote

PCM-Programmer,

Thanks for the tip.

I see how to use stream in #use i2c.
Code:

#use i2c(master, sda=PIN_C4, scl=PIN_D3, stream=SlowI2c))
#use i2c(master, sda=PIN_C4, scl=PIN_C3, stream=FastI2c))

However, it seems like I'll have to hardcode two separate sections of code to deal with each stream. Unless there is a way to pass stream in as an argument. The manual does not spec the datatype for stream. Is it possible to do something like this:

Code:

ReadExEepromInt (long addr, unknown-type stream){
      int data;

      i2c_start(stream);
      i2c_write(stream,0xa0);
      i2c_write(stream,addr>>8);
      i2c_write(stream,addr);
      i2c_start(stream);
      i2c_write(stream,0xa1);//control byte with R/#W set to 1

         data= i2c_read(stream,0); //sequential reads

      i2c_stop(stream);
      return(data);

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 6:04 pm     Reply with quote

The compiler doesn't allow streams to be passed as a parameter.
stephanhwolf



Joined: 03 Sep 2012
Posts: 4

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 6:49 pm     Reply with quote

Yup, that's what I thought.

Thanks again for your help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Tue Sep 04, 2012 1:37 am     Reply with quote

Remember though, you can encapsulate the I2C routines. So:
Code:

int1 second_stream=FALSE;

#separate
void my_i2c_stop() {
    if (second_stream) i2c_stop(STREAM2);
    else i2c_stop(STREAM1);
}

and similarly for each of the other routines.

Then you just call 'my_i2c_start', 'my_i2c_stop' etc., and change 'second_stream' to TRUE/FALSE, according to which stream you want.

This way the required two separate code copies are produced just once (hence the #separate).

Best Wishes
stephanhwolf



Joined: 03 Sep 2012
Posts: 4

View user's profile Send private message

PostPosted: Tue Sep 04, 2012 10:28 am     Reply with quote

Hi Ttelmah,
I don't really get the #separate directive. Seems to me subroutines ought to be separate by default, and only #inline if so directed.

Or, does the compiler decide whether to make subroutines separate or inline based on frequency of occurrence?
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