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

SOLVED: i2c_transfer not working

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



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

SOLVED: i2c_transfer not working
PostPosted: Thu Jun 01, 2023 12:07 am     Reply with quote

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: 19537

View user's profile Send private message

PostPosted: Thu Jun 01, 2023 1:21 am     Reply with quote

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: 357
Location: South Africa

View user's profile Send private message

PostPosted: Thu Jun 01, 2023 4:43 am     Reply with quote

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: 19537

View user's profile Send private message

PostPosted: Thu Jun 01, 2023 6:21 am     Reply with quote

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: 357
Location: South Africa

View user's profile Send private message

PostPosted: Thu Jun 01, 2023 6:42 am     Reply with quote

Got a new version yesterday from CCS as there were faults in 5.115
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Thu Jun 01, 2023 6:46 am     Reply with quote

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: 19537

View user's profile Send private message

PostPosted: Thu Jun 01, 2023 7:00 am     Reply with quote

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
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