lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

I2C crashes with BCM2835 library functions

Tue Mar 31, 2015 2:08 pm

Hi,

I have this MPL3115A2 connected to my Raspberry Pi SDA and SCL pins. When I run "i2cdetect -y 1" it shows 0x60 like it should be. After I run my code it allways crashes to line "bcm2835_i2c_begin" and then the address disappears.

However, when I tried with Raspberry Pis user space I2C access code it at least ran fine these lines without crashing and it doesn't mess i2c device address:
fd = open(fileName, O_RDWR)) < 0)
ioctl(fd, I2C_SLAVE, address) < 0)

The MPL3115A2 sensor require repeated start so if could do that with the user space code i could forget those bcm2835 library functions. I am wondering if that is possible with the user space code.

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Tue Mar 31, 2015 2:27 pm

If you are using a Pi2 check that you have an up to date version of the library.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Tue Mar 31, 2015 2:39 pm

joan wrote:If you are using a Pi2 check that you have an up to date version of the library.
I'm using Pi1 model b+.

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Tue Mar 31, 2015 2:55 pm

In that case you'll probably have to use combined transactions or bit banging to get a repeated start.

Assuming combined transactions you'd have to use the I2C_RDWR ioctl and format a struct i2c_rdwr_ioctl_data rdwr_data.

You then need to set /sys/module/i2c_bcm2708/parameters/combined to Y and do the transaction.

I'd set it to N afterwards as in my experience it screws up ordinary I2C if you don't.

If you search some of those terms you should find example code.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Tue Mar 31, 2015 4:49 pm

Ok, thank you for the reply. I'll try that combined transaction then.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Fri Apr 10, 2015 2:45 pm

struct i2c_msg rdwr_msgs[2] = {
{ // Start address
.addr = 0x50,
.flags = 0, // write
.len = 1,
.buf = &reg_address
},
{ // Read buffer
.addr = 0x50,
.flags = I2C_M_RD, // read
.len = 16,
.buf = buffer
}
};

I think this is the method to to de compined transaction but I'm confused with the parameters of the struct. For intsance if I want to set register 0x13 to a value 0x07 how do I set those parameters?

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Fri Apr 10, 2015 2:56 pm

I think the following fragment should be what you need.

char values[2]={0x13, 0x07};

.addr = 0x50
.flags = 0 // write
.len = 2
.buf = &values

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Fri Apr 10, 2015 3:44 pm

Ok, one question left. Do I need that read buffer when setting those registers?

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Fri Apr 10, 2015 4:18 pm

lihakimpale wrote:Ok, one question left. Do I need that read buffer when setting those registers?
You always need a buffer of some sort. It'll either point to the bytes to be written or to an array to hold the bytes to be read.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sat Apr 11, 2015 1:49 pm

Thank you joan.

I am still not able to get it work. Eclipse gave me syntax error of that structure definition so i changed it but I'm not sure if I made it right. Here is the beginning of my code :

int file = 0;
const char *fileName = "/dev/i2c-1";
unsigned char values[2] = { };
struct i2c_msg rdwr_msgs[2];
struct i2c_rdwr_ioctl_data rdwr_data;

values[0]=0x26;
values[1]=0x00;

file = open(fileName, O_RDWR );

rdwr_data.msgs = rdwr_msgs;
rdwr_data.nmsgs = 2;

rdwr_data.msgs[0].addr = MPL3115A2_ADDR;
rdwr_data.msgs[0].flags = 0;
rdwr_data.msgs[0].len = 2;
rdwr_data.msgs[0].buf = values;

rdwr_data.msgs[1].addr = MPL3115A2_ADDR;
rdwr_data.msgs[1].flags = I2C_M_RD; // read
rdwr_data.msgs[1].len = 2;
rdwr_data.msgs[1].buf = values;

ioctl( file, I2C_RDWR, &rdwr_data );

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sat Apr 11, 2015 2:44 pm

I found one example where the writing operation was made with function call write(). The combined transaction was used when reading from the slave.

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Sat Apr 11, 2015 2:55 pm

I had a quick look and can't see anything obviously wrong. Have you switched the combined flag on separately?

The current version of pigpio (V31) has limited support for such transactions. It might be worth looking at the code I use (pigpio.c, line 3420, i2cTransaction). I haven't decided to leave it in or remove it.

This is test code I used.

Code: Select all

/*
i2c_transaction_test.c
2015-02-02
Public Domain

gcc -o itt i2cTransaction_test.c -lpigpio -lrt -lpthread
sudo ./itt

A test of the pigpio i2cTransaction function.

 struct i2c_msg rdwr_msgs[2] = {
    {  // Start address
      .addr = 0x50,
      .flags = 0, // write
      .len = 1,
      .buf = &reg_address
    },
    { // Read buffer
      .addr = 0x50,
      .flags = I2C_M_RD, // read
      .len = 16,
      .buf = buffer
    }
  };

  struct i2c_rdwr_ioctl_data rdwr_data = {
    .msgs = rdwr_msgs,
    .nmsgs = 2
  };

  file = open( "/dev/i2c-1", O_RDWR );
...

  result = ioctl( file, I2C_RDWR, &rdwr_data );
*/

#include <stdio.h>

#include <pigpio.h>

uint8_t buffer[]={0xAA, 0x55, 0x0F, 0xF0, 0x00, 0xFF};

pi_i2c_msg_t rdwr_msgs[]=
{
   {.addr = 0x1E, .flags = PI_I2C_M_WR, .len = 0, .buf = buffer},
   {.addr = 0x1E, .flags = PI_I2C_M_RD, .len = 1, .buf = buffer},
   {.addr = 0x53, .flags = PI_I2C_M_WR, .len = 0, .buf = buffer},
   {.addr = 0x53, .flags = PI_I2C_M_RD, .len = 1, .buf = buffer},
   {.addr = 0x68, .flags = PI_I2C_M_WR, .len = 0, .buf = buffer},
   {.addr = 0x68, .flags = PI_I2C_M_RD, .len = 1, .buf = buffer},
};

int main(int argc, char *argv[])
{
   int i, h;

   int status;

   if (gpioInitialise() < 0) return 1;

   printf("start piscope, then press return\n");

   getchar();

   h = i2cOpen(1, 0x1E, 0);

   if (h >= 0)
   {
      for (i=0; i<10; i++)
      {
         status = i2cTransaction(h, rdwr_msgs, 6);

         printf("i2cTransaction status = %d\n", status);

         usleep(20000);
      }

      i2cClose(h);
   }

   printf("stop piscope, then press return\n");

   getchar();

   gpioTerminate();
}
I noticed that leaving the combined flag set seem to screw up ordinary I2C transactions.

You can reset the flag with the following command.

sudo sh -c "echo 0 >/sys/module/i2c_bcm2708/parameters/combined"

and set the flag with

sudo sh -c "echo 1 >/sys/module/i2c_bcm2708/parameters/combined"

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sat Apr 11, 2015 4:50 pm

I ran that test code and it gave these return values:

2015-04-11 19:46:35 i2cTransaction: i2cTransaction retval=-1
i2cTransaction status = -106

What does that tell me?

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Sat Apr 11, 2015 5:00 pm

Error -106 is a part of a combined transaction failed.

It just means you don't have the same devices connected to the I2C bus that I have when I run that test. The test was an example of the sort of code you need. You need to adapt it to fit your device(s).

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sun Apr 12, 2015 4:59 pm

Now I am able to get something out of the pressure register but the first element of the pbuf array is zero.

Code: Select all

//Write data
void write_register(unsigned char reg, unsigned char value, int *p_fd)
{
	int result = 0;
	unsigned char buf[2] = { 0 };
	struct i2c_msg rdwr_msg[1];
	struct i2c_rdwr_ioctl_data rdwr_data1;

    rdwr_data1.msgs = rdwr_msg;
    rdwr_data1.nmsgs = 1;

	buf[0]=reg;
	buf[1]=value;

	if(ioctl(*p_fd, I2C_SLAVE, MPL3115A2_ADDR) < 0)
	{
			printf("Unable to get bus access to talk to slave\n");
			close(*p_fd);
			return;
	}

	  rdwr_data1.msgs[0].addr = MPL3115A2_ADDR;
	  rdwr_data1.msgs[0].flags = 0;
	  rdwr_data1.msgs[0].len = 1;
	  rdwr_data1.msgs[0].buf = buf;

	  result = ioctl( *p_fd, I2C_RDWR, &rdwr_data1 );

	  if ( result < 0 )
	  {
	    printf( "rdwr ioctl error: %d\n", errno );
	    perror( "reason" );
	  }
}

int main(void){

	int fd = 0, result = 0;
	int *p_fd;
	float pressure = 0;

	unsigned char p_out_address[3] = { };
	int i = 0;
	unsigned char pbuf[6] = { 0 };
	struct i2c_msg rdwr_msgs[2];
	struct i2c_rdwr_ioctl_data rdwr_data;

	if((fd=open(fileName, O_RDWR)) < 0)
	{
			printf("Failed to open i2c port");

			return 1;
	}

	if(ioctl(fd, I2C_SLAVE, MPL3115A2_ADDR) < 0)
	{
			printf("Unable to get bus access to talk to slave\n");
			close(fd);
			return 1;
	}

	p_fd = &fd;

	//Set registers
	 write_register(0x26,0x00, p_fd); //Standby mode
	 write_register(0x26, 0x38, p_fd); //Barometer mode with osr128
	 write_register(0x13,0x07, p_fd); //Enable dataflags
	 write_register(0x26,0x39, p_fd); //Set active

	 p_out_address[0] = 0x01;
	 p_out_address[1] = 0x02;
	 p_out_address[2] = 0x03;

	 //Read data
         rdwr_data.msgs = rdwr_msgs;
         rdwr_data.nmsgs = 2;

	  rdwr_data.msgs[0].addr = MPL3115A2_ADDR;
	  rdwr_data.msgs[0].flags = 0;
	  rdwr_data.msgs[0].len = 3;
	  rdwr_data.msgs[0].buf = p_out_address;

	  rdwr_data.msgs[1].addr = MPL3115A2_ADDR;
	  rdwr_data.msgs[1].flags = I2C_M_RD; // read
	  rdwr_data.msgs[1].len = 3;
	  rdwr_data.msgs[1].buf = pbuf;

	  result = ioctl( fd, I2C_RDWR, &rdwr_data );

	  if ( result < 0 )
	  {
	    printf( "rdwr ioctl error: %d\n", errno );
	    perror( "reason" );
	  }

	  else
	  {
	    printf( "rdwr ioctl OK\n" );

	    for ( i = 0; i < 3; ++i )
	    {
	      printf( "%d \n", pbuf[i] );
	    }
	  }

	  pressure = (pbuf[0]<<16) | (pbuf[1]<<8) | (pbuf[2]);
	  printf("pressure: %0.2f Pa\n", pressure);

	return 0;
}

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Mon Apr 13, 2015 2:33 pm

Seems that it is working completely randomly. Sometimes it gives some output values and sometimes the output values are just zeros.

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Mon Apr 13, 2015 2:46 pm

lihakimpale wrote:Seems that it is working completely randomly. Sometimes it gives some output values and sometimes the output values are just zeros.
With code similar to your previous post?

Unfortunately I've not got any I2C chips which need this type of special feature so I'm not able to test myself. I'm just going on what I've gleaned from other posts.

If you have the kernel sources have a look at /linux/drivers/i2c/busses/i2c-bcm2708.c to see how the combined flag is handled.

Perhaps you need to bit bang. I have posted a Python module which bit bangs I2C at a low level. The next version of pigpio will probably have in-built support for bit-banging so that repeated starts and clock stretching can be used.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Mon Apr 13, 2015 5:09 pm

Yes with the same code. Only difference was reboot of Raspberry Pi.

Need to work with this a little while and if this isn't getting any forward then I think the next option is that bit banging.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sat Apr 25, 2015 11:19 am

This is unbelievable... I can't even read the WHOAMI register.. There has to be something wrong elsewhere than in my code.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sat Apr 25, 2015 1:00 pm

Hmm am I right that there is already pull up resistors on the sda and scl lines of Raspberry Pi? I think this breakout board has integrated pull up resistors so might that be the problem here?

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Sat Apr 25, 2015 1:24 pm

lihakimpale wrote:Hmm am I right that there is already pull up resistors on the sda and scl lines of Raspberry Pi? I think this breakout board has integrated pull up resistors so might that be the problem here?
Pins 3 and 5 (SDA/SCL) have hard-wired 1k8 pull-ups to 3V3.

You'd need to ensure that any other pull-ups are only to 3V3 at most, otherwise the Pi's gpios may be damaged. Even if the other pull-ups are to 3V3 it's probably best to disable them if possible.
Last edited by joan on Sat Apr 25, 2015 1:25 pm, edited 1 time in total.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sat Apr 25, 2015 1:25 pm

I made some research and yes those i2c pins has 1k8 pull up resistors and the breakout board has 4k7 pull ups. Can I somehow disable those pull ups on Raspberry Pi?

User avatar
rpdom
Posts: 16329
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: I2C crashes with BCM2835 library functions

Sat Apr 25, 2015 6:43 pm

lihakimpale wrote:I made some research and yes those i2c pins has 1k8 pull up resistors and the breakout board has 4k7 pull ups. Can I somehow disable those pull ups on Raspberry Pi?
Only by physically desoldering them from the board.

lihakimpale
Posts: 80
Joined: Tue Jul 22, 2014 4:12 pm

Re: I2C crashes with BCM2835 library functions

Sun Apr 26, 2015 8:51 am

What do you think? Is that double pull up causing me the problems? Should I try to desolder them from the breakout board.

User avatar
joan
Posts: 14755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: I2C crashes with BCM2835 library functions

Sun Apr 26, 2015 9:03 am

lihakimpale wrote:What do you think? Is that double pull up causing me the problems? Should I try to desolder them from the breakout board.
My maths says that gives the equivalent of 1300 ohm. I don't know but it doesn't sound too low to work.

What bps are you using? Perhaps drop to 50 kbps or less for testing.

Return to “Interfacing (DSI, CSI, I2C, etc.)”