| View previous topic :: View next topic   | 
	
	
	
		| Author | 
		Message | 
	
	
		
			alan
 
 
  Joined: 12 Nov 2012 Posts: 358 Location: South Africa 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| SOLVED: i2c_transfer not working | 
			 
			
				 Posted: Thu Jun 01, 2023 12:07 am     | 
				     | 
			 
			
				
  | 
			 
			
				Good day.
 
Have a problem where I can not get i2c_transfer to work.
 
Old i2c_start works fine. Needed to change to i2c_transfer as the compiler complains on a new chip
 
 
Old PIC:  PIC16F18325
 
New PIC: PIC18F04Q41
 
 
 	  | Code: | 	 		  
 
#include <18F04Q40.h>
 
 
#FUSES NOMCLR, NOPROTECT
 
#use delay(internal=8000000)
 
#include <stdint.h>
 
 
#pin_select SDA1 = PIN_C5
 
#pin_select SCL1 = PIN_C4
 
#use I2C(Master,I2C1,stream = MPU6050)
 
 
void main(void) {
 
  int8_t reg_addr[2];
 
  output_toggle(LED_CHARGING);
 
  delay_ms(500);
 
  output_toggle(LED_CHARGING);
 
  delay_ms(500);
 
  output_toggle(LED_CHARGING);
 
  delay_ms(100);
 
//  i2c_start();
 
//  i2c_write(MPU6050_SLAVE_WRT);
 
//  i2c_write(MPU6050_SMPLRT_DIV);   
 
//  i2c_write(0x07);
 
//  i2c_stop();
 
  reg_addr[0] = MPU6050_SMPLRT_DIV;
 
  reg_addr[1] = 0x07;
 
  i2c_transfer(MPU6050,MPU6050_SLAVE_WRT,reg_addr,2);
 
 
    while (TRUE) {
 
  output_toggle(LED_CHARGING);
 
  delay_ms(500);
 
  }
 
 | 	  
 
Stop just after i2c_transfer
  Last edited by alan on Thu Jun 01, 2023 6:47 am; edited 1 time in total | 
			 
		  | 
	
	
		  | 
	
	
		
			Ttelmah
 
 
  Joined: 11 Mar 2010 Posts: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 01, 2023 1:21 am     | 
				     | 
			 
			
				
  | 
			 
			
				What compiler version???
 
Vital when asking almost any question.
 
 
Particularly vital here, since the behaviour of I2C_transfer changed with
 
compiler version. 
 
 
When this function was first added, the 'count' at the end was the value
 
put into the count register on the chip. This needs to be one greater than
 
the number of bytes you want to send, since the address byte also counts.
 
However it now only requires the number of bytes you want to send.
 
So on a recent compiler, what you post is right, but on older compilers,
 
you need 3, instead of 2 for the byte count.....
 
 
Some other little thoughts.
 
On the old chip, was the clock rate the same?. The I2C might be running
 
faster now. Add a baud value to the I2C setup so this is fixed.
 
You say 18F04Q41, but the code shows 18F04Q40.
 
You are running at 3.3v?. Both chips accept this, but nice to know. 
 
On I2C_transfer, you don't have to worry about read and write addresses.
 
The command just takes the device address and automatically sets the 
 
low bit of this for a read. So change to just having the device address 
 
rather than read/write addresses. 
 
 
On some of these later chips, there are slew rate controls on the pins.
 
Yours is one where this applies. So you need to turn this off
 
 
set_slow_slew_c(FALSE);
 
 
near the start of the code, before the I2C is used. It defaults to on. | 
			 
		  | 
	
	
		  | 
	
	
		
			alan
 
 
  Joined: 12 Nov 2012 Posts: 358 Location: South Africa 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 01, 2023 4:43 am     | 
				     | 
			 
			
				
  | 
			 
			
				Oh sorry Ver 5.116
 
 
Should be 18F04Q40
 
Same clk rate
 
Both at 3.3V
 
 
Will try the slew rate
 
 
Thank you | 
			 
		  | 
	
	
		  | 
	
	
		
			Ttelmah
 
 
  Joined: 11 Mar 2010 Posts: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 01, 2023 6:21 am     | 
				     | 
			 
			
				
  | 
			 
			
				Er.
 
5.115 is the latest compiler on the download site.
 
If you have 5.116, it'll be a beta, and you should talk to CCS, | 
			 
		  | 
	
	
		  | 
	
	
		
			alan
 
 
  Joined: 12 Nov 2012 Posts: 358 Location: South Africa 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 01, 2023 6:42 am     | 
				     | 
			 
			
				
  | 
			 
			
				| Got a new version yesterday from CCS as there were faults in 5.115 | 
			 
		  | 
	
	
		  | 
	
	
		
			alan
 
 
  Joined: 12 Nov 2012 Posts: 358 Location: South Africa 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 01, 2023 6:46 am     | 
				     | 
			 
			
				
  | 
			 
			
				Got it working.
 
I know the old hands here don't like the #USE fast_io, but I do. Previously you need to set the i2c pins as inputs to work, yet it looks like when using dedicated i2c you have to set them as outputs to work. | 
			 
		  | 
	
	
		  | 
	
	
		
			Ttelmah
 
 
  Joined: 11 Mar 2010 Posts: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 01, 2023 7:00 am     | 
				     | 
			 
			
				
  | 
			 
			
				Most of the long term posters will use fast_io _sometimes_. The point is 
 
very rarely. What is hated is people routinely using it, because it 
 
makes errors vastly more likely.
 
Normally when a peripheral is attached to the pins on a PPS chip, it 
 
overrides the TRIS settings.
 
On your chip the data sheet says that the pins must be set as open drain
 
outputs. So the pins actually need their TRIS bits set to 0, but also
 
the ODCON bits, otherwise the pins will be driven high, which invalidates
 
things like clock stretching from the slave. 
 
So using FAST_IO without setting ODCON risks drawing excessive current.
 
So get rid of your fast_io setting, and use:
 
 	  | Code: | 	 		  
 
output_drive(PIN_C4); //These set the two TRIS bits to 0
 
output_drive(PIN_C5); //without affecting anything else
 
set_open_drain_c(0B00110000); //set these two bits as open_drain
 
 | 	 
  | 
			 
		  | 
	
	
		  | 
	
	
		 |