| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| stephanhwolf 
 
 
 Joined: 03 Sep 2012
 Posts: 4
 
 
 
			    
 
 | 
			
				| #use i2c not changing pins with 18f4520 |  
				|  Posted: Mon Sep 03, 2012 3:48 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Sep 03, 2012 4:21 pm |   |  
				| 
 |  
				|  	  | 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Sep 03, 2012 5:17 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Sep 03, 2012 6:04 pm |   |  
				| 
 |  
				| The compiler doesn't allow streams to be passed as a parameter. |  | 
	
		|  | 
	
		| stephanhwolf 
 
 
 Joined: 03 Sep 2012
 Posts: 4
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Sep 03, 2012 6:49 pm |   |  
				| 
 |  
				| Yup, that's what I thought. 
 Thanks again for your help.
 |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Sep 04, 2012 1:37 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Sep 04, 2012 10:28 am |   |  
				| 
 |  
				| 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?
 |  | 
	
		|  | 
	
		|  |