I2C and Invensense MPU6050 Driver

5,948 views
Skip to first unread message

clarkbr...@gmail.com

unread,
Oct 15, 2013, 6:02:59 PM10/15/13
to beagl...@googlegroups.com

We are using the Invensense MPU6050 IMU on I2C with Beaglebone Black (Angstrom 3.8.13). We can use I2C-tools and file I/O thru /dev/i2c but the read speed is disappointingly slow.  We only read the 3x gyros and 3x accels (each one byte at a time plus the 2 byte temperature reading) and it takes ~2msecs.  My estimate of the I2C bus cycles for a block read suggests this should take ~160 bus cycles or .38msec on a 400MHz I2C bus.

The distribution includes the Invensense driver inv-mpu6050.ko but there is no indication that reading through /dev/i2c invokes it.  This is a very popular IMU and Invensense widely distributes the driver over many Linux platforms.  The driver source includes “successful installation will create two directories under /sys/bus/iio/devices” and lists the files there (aka functions). I can never get these to show up.

I can “insmod /lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050/inv-mpu6050.ko” and “echo inv-mpu6050 0x68 > /sys/class/i2c-adapter/i2c-1/new_device”. This causes a new directory named 1-0068 to show in /sys/class/i2c-adapter/i2c-1with entries like name and modalias but no functions.  It never shows in /sys/bus/iio/devices.

What constitutes “successful installation”? 

What else is needed to get the inv-mpu6050 to expose functions in /sys/bus/iio/devices like the driver sources says?

Beaglebone Black uses bone_capemgr for exposing driver functions for many devices.  “echo inv-mpu6050 0x68 > /sys/devices/bone_capmgr.9/slots” raises the gripe “write error: no such file or directory”.  (I can successfully load the am33xx_pwm driver this way.) Is this because there is no matching DT fragment in /lib/firmware? Is the inv-mpu6050 driver supposed to be invoked thru cape manager?

Then, most importantly, if I did read and write through the /sys tree using the Invensense driver would it be faster than /dev/i2c?
Help on sorting this out would be much appreciated.

Jacek Radzikowski

unread,
Oct 15, 2013, 8:33:15 PM10/15/13
to beagleboard
You're barking at a wrong tree. /sys/devices/bone_capmgr.9/slots is used to load device tree overlays and has nothing to do with devices on I2C bus. The correct place to write to instantiate a new i2c device is /sys/bus/i2c/devices/i2c-X/new_device (substitute X with bus number to which the chip is connected). The echo command in your case would look like something like this:

echo inv-mpu6050 0x68 > /sys/bus/i2c/devices/i2c-X/new_device

j.



--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Given a choice between two theories, take the one which is funnier

David Goodenough

unread,
Oct 16, 2013, 4:58:26 AM10/16/13
to beagl...@googlegroups.com
On Wednesday 16 Oct 2013, Jacek Radzikowski wrote:
> You're barking at a wrong tree. /sys/devices/bone_capmgr.9/slots is used to
> load device tree overlays and has nothing to do with devices on I2C bus.
This is not quite true. While you can access the I2C bus directly without
a device tree entry, if there is an overlay you can tell the kernel that this
device is expected to be there, and if the driver is DTB enabled you can
get it loaded and configured for you.

David
> The correct place to write to instantiate a new i2c device is
> /sys/bus/i2c/devices/i2c-X/new_device (substitute X with bus number to
> which the chip is connected). The echo command in your case would look like
> something like this:
>
> echo inv-mpu6050 0x68 > /sys/bus/i2c/devices/i2c-X/new_device
>
> j.
>
> On Tue, Oct 15, 2013 at 6:02 PM, <clarkbr...@gmail.com> wrote:
> > We are using the Invensense MPU6050 IMU on I2C with Beaglebone Black
> > (Angstrom 3.8.13). We can use I2C-tools and file I/O thru /dev/i2c but
> > the read speed is disappointingly slow. We only read the 3x gyros and
> > 3x accels (each one byte at a time plus the 2 byte temperature reading)
> > and it takes ~2msecs. My estimate of the I2C bus cycles for a block
> > read suggests this should take ~160 bus cycles or .38msec on a 400MHz
> > I2C bus. ******
> >
> > The distribution includes the Invensense driver inv-mpu6050.ko but there
> > is no indication that reading through /dev/i2c invokes it. This is a
> > very popular IMU and Invensense widely distributes the driver over many
> > Linux platforms. The driver source includes “successful installation
> > will create two directories under /sys/bus/iio/devices” and lists the
> > files there (aka functions). I can never get these to show up.****
> >
> > I can “insmod
> > /lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050/inv-mpu6050.ko”
> > and “echo inv-mpu6050 0x68 > /sys/class/i2c-adapter/i2c-1/new_device”.
> > This causes a new directory named 1-0068 to show in
> > /sys/class/i2c-adapter/i2c-1with entries like name and modalias but no
> > functions. It never shows in /sys/bus/iio/devices.****
> >
> > What constitutes “successful installation”? ****
> >
> > What else is needed to get the inv-mpu6050 to expose functions in
> > /sys/bus/iio/devices like the driver sources says?****
> >
> > Beaglebone Black uses bone_capemgr for exposing driver functions for many
> > devices. “echo inv-mpu6050 0x68 > /sys/devices/bone_capmgr.9/slots”
> > raises the gripe “write error: no such file or directory”. (I can
> > successfully load the am33xx_pwm driver this way.) Is this because there
> > is no matching DT fragment in /lib/firmware? Is the inv-mpu6050 driver
> > supposed to be invoked thru cape manager?****

clarkbr...@gmail.com

unread,
Oct 16, 2013, 2:29:34 PM10/16/13
to beagl...@googlegroups.com
J.
Ok, but I did the new_device, got a directory entry for 1-0068 (my new address), but didn't get anything I recognized as the MPU6050 driver functions. Can you guess what caused that? Do they show up in this 1-0068 dir or somewhere else in the /sysfs? or over in /dev/i2c? If I am successful, do you see any reason this will be faster than just file i/o thru /dev/i2c?   --Clark

clarkbr...@gmail.com

unread,
Oct 16, 2013, 2:33:00 PM10/16/13
to beagl...@googlegroups.com, david.go...@linkchoose.co.uk
David,
Good for you. I don't understand that connection. If I get the driver and a DTB loaded, where will it show up? Possible answers are under bone_capmgr, under /sys/...i2c-1, and under /dev/i2c. And do you have any reason to believe this will be faster than simply file i/o-ing thru /dev/i2c? --Clark

David Goodenough

unread,
Oct 16, 2013, 2:51:26 PM10/16/13
to beagl...@googlegroups.com
On Wednesday 16 Oct 2013, clarkbr...@gmail.com wrote:
> David,
> Good for you. I don't understand that connection. If I get the driver and a
> DTB loaded, where will it show up? Possible answers are under bone_capmgr,
> under /sys/...i2c-1, and under /dev/i2c. And do you have any reason to
> believe this will be faster than simply file i/o-ing thru /dev/i2c? --Clark
If you want raw file access to the device, then your application is acting
as the device driver so the kernel does not need to know anything other than
how to deal with the I2C hardware - which it clearly does. However if you
want a device driver (and you seemed to be looking for one or rather the
files that is presents) then you need to tell the kernel to load the driver.
This can be done manually, or you can configure it - and the way that seems
to becoming the standard is the device tree. Your choice.

David
>
> On Wednesday, October 16, 2013 1:58:26 AM UTC-7, David Goodenough wrote:
> > On Wednesday 16 Oct 2013, Jacek Radzikowski wrote:
> > > You're barking at a wrong tree. /sys/devices/bone_capmgr.9/slots is
> > > used
> >
> > to
> >
> > > load device tree overlays and has nothing to do with devices on I2C
> > > bus.
> >
> > This is not quite true. While you can access the I2C bus directly
> > without a device tree entry, if there is an overlay you can tell the
> > kernel that this
> > device is expected to be there, and if the driver is DTB enabled you can
> > get it loaded and configured for you.
> >
> > David
> >
> > > The correct place to write to instantiate a new i2c device is
> > > /sys/bus/i2c/devices/i2c-X/new_device (substitute X with bus number to
> > > which the chip is connected). The echo command in your case would look
> >
> > like
> >
> > > something like this:
> > >
> > > echo inv-mpu6050 0x68 > /sys/bus/i2c/devices/i2c-X/new_device
> > >
> > > j.
> > >
> > > On Tue, Oct 15, 2013 at 6:02 PM, <clarkbr...@gmail.com <javascript:>>
> > Groups
> >
> > > > "BeagleBoard" group.
> > > > To unsubscribe from this group and stop receiving emails from it,
> > > > send
> >
> > an
> >
> > > > email to beagleboard...@googlegroups.com <javascript:>.

AIW

unread,
Oct 17, 2013, 12:47:44 PM10/17/13
to beagl...@googlegroups.com
Some good info on I2C tools at http://www.acmesystems.it/i2c

Python and the adafruit BBIO I2C library makes it very easy to use I2C on Beaglebone Black as well. Python import smbus is fairly easy to use too. Some examples of use is available in the code I provide for my radio project here....www.aiwindustries.com

Not trying to sell the product, but I know that the I2C function was giving me some issues so I'm just trying to help the community. Python code is available to download and look at usage so feel free.

clarkbr...@gmail.com

unread,
Oct 17, 2013, 6:12:22 PM10/17/13
to beagl...@googlegroups.com, richar...@noaa.gov
AIW:
I went back thru the adafruit library and didn't find anything specific on I2C, although it is listed as a topic.  I have been looking at their github adafruit-beaglebone-io-python library. I also found and looked thru PyBBIO. Even tho I'm not using Python, I can see the access mechanisms that they use.
I can use the MPU6050 device ok enough just reading via /dev/i2c/i2c-x, but that is too slow.
I'm trying to figure out how to invoke and use the inv-mpu6050 driver and adafruit doesn't use that. 
Thx -- Clark

AIW

unread,
Oct 18, 2013, 7:28:13 AM10/18/13
to beagl...@googlegroups.com, clarkbr...@gmail.com
I did find some more python data regarding the MPU6050 here. I believe it was originally designed for R-Pi, but its based off smbus so it should work on BBB as well. Not sure if this will be any faster than how your doing it but just looking at options.

Jason Kridner

unread,
Oct 29, 2013, 2:19:14 PM10/29/13
to beagl...@googlegroups.com, richar...@noaa.gov
You are running at 400kHz, not 400MHz, right? I2C doesn't do 400MHz.

>>>
>>> The distribution includes the Invensense driver inv-mpu6050.ko but there
>>> is no indication that reading through /dev/i2c invokes it. This is a very
>>> popular IMU and Invensense widely distributes the driver over many Linux
>>> platforms. The driver source includes “successful installation will create
>>> two directories under /sys/bus/iio/devices” and lists the files there (aka
>>> functions). I can never get these to show up.
>>>
>>> I can “insmod
>>> /lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050/inv-mpu6050.ko” and
>>> “echo inv-mpu6050 0x68 > /sys/class/i2c-adapter/i2c-1/new_device”. This
>>> causes a new directory named 1-0068 to show in
>>> /sys/class/i2c-adapter/i2c-1with entries like name and modalias but no
>>> functions. It never shows in /sys/bus/iio/devices.

I don't have an MPU6050, but I just ordered a couple on express
overnight from Sparkfun.

Here's the behavior I'm seeing without the board connected:

root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050# ls
inv-mpu6050.ko
root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050#
dmesg | tail -1
[ 2992.799594] i2c i2c-1: new_device: Instantiated device inv-mpu6050 at 0x68
root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050# lsmod
Module Size Used by
ip_tables 8294 0
x_tables 15072 1 ip_tables
g_multi 55905 2
libcomposite 15228 1 g_multi
rfcomm 25106 0
ircomm_tty 14503 0
ircomm 8846 1 ircomm_tty
irda 89974 2 ircomm_tty,ircomm
ipv6 229989 14
hidp 10112 0
bluetooth 146100 4 hidp,rfcomm
rfkill 16510 2 bluetooth
autofs4 17432 2

I looked for the installed device:

root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050#
cat /sys/bus/iio/devices/iio*/name
tiadc
root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050#
ls /sys/bus/iio/devices/iio* -d
/sys/bus/iio/devices/iio:device0

It is clearly missing per the documentation
(https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-iio-mpu6050)
that says there should be a sysfs entry there.

Just in case I could get it to show up, I did try manually doing a modprobe.

root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050#
modprobe inv-mpu6050
root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050# lsmod
Module Size Used by
inv_mpu6050 7190 0
ip_tables 8294 0
x_tables 15072 1 ip_tables
g_multi 55905 2
libcomposite 15228 1 g_multi
rfcomm 25106 0
ircomm_tty 14503 0
ircomm 8846 1 ircomm_tty
irda 89974 2 ircomm_tty,ircomm
ipv6 229989 14
hidp 10112 0
bluetooth 146100 4 hidp,rfcomm
rfkill 16510 2 bluetooth
autofs4 17432 2
root@beaglebone:/lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050#
ls /sys/bus/iio/devices/iio* -d
/sys/bus/iio/devices/iio:device0

Of course, this all makes perfect sense since the driver should exit
upon failing the 'probe':
https://github.com/beagleboard/linux/blob/3.8/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c#L658

I'd have to look up how to turn on more debugging statements. I tried
the hints at http://elinux.org/Debugging_by_printing, but I'm
surprised the 'dmesg' log didn't show any extra errors.


>>>
>>> What constitutes “successful installation”?
>>>
>>> What else is needed to get the inv-mpu6050 to expose functions in
>>> /sys/bus/iio/devices like the driver sources says?

I don't think anything else should be required. To build the kernel
properly, there are a few things that need to be enabled
(https://github.com/beagleboard/linux/blob/3.8/drivers/iio/imu/inv_mpu6050/Kconfig):

INV_MPU6050_IIO, I2C, SYSFS, IIO_BUFFER, IIO_TRIGGERED_BUFFER

And they are all there:
https://github.com/beagleboard/kernel/blob/3.8/configs/beaglebone#L3676

>>>
>>> Beaglebone Black uses bone_capemgr for exposing driver functions for many
>>> devices. “echo inv-mpu6050 0x68 > /sys/devices/bone_capmgr.9/slots” raises
>>> the gripe “write error: no such file or directory”. (I can successfully
>>> load the am33xx_pwm driver this way.) Is this because there is no matching
>>> DT fragment in /lib/firmware?

Yes.

>>> Is the inv-mpu6050 driver supposed to be
>>> invoked thru cape manager?

No, because the I2C bus software provides another mechanism. I believe
you could create a DT fragment, but I think it is pointless.

>>>
>>> Then, most importantly, if I did read and write through the /sys tree
>>> using the Invensense driver would it be faster than /dev/i2c?
>>> Help on sorting this out would be much appreciated.

Yes, because the driver running in kernel mode is going to be higher
performance than your pokes from userspace.

>
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to the Google Groups
> "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to beagleboard...@googlegroups.com.

Jason Kridner

unread,
Oct 31, 2013, 4:32:46 PM10/31/13
to beagl...@googlegroups.com, richar...@noaa.gov
I bought https://www.sparkfun.com/products/11028 and played with it
briefly before being distracted and again today, but I don't
understand why I'm not able to get it to reply to me.

I have the following connections:
VCC: P9_4 (VDD_3V3)
GNC: P9_1 (GND)
INT: P9_11 (GPIO)
FSYNC: -
SCL: P9_19 (I2C2_SCL)
SDA: P9_20 (I2C2_SDA)
VIO: P9_3 (VDD_3V3)
CLK: -
ASCL: -
ASDA: -

I then perform:

root@beaglebone:~# i2cdetect -y -r 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Very confused why it doesn't show up.

Since you have it responding to you, how do you have it wired?

Joshua Datko

unread,
Oct 31, 2013, 11:57:08 PM10/31/13
to beagl...@googlegroups.com, richar...@noaa.gov
So I've been struggling with I2C.  Somebody on this list gave me the tip to do:

echo BB-I2C1 > /sys/devices/bone_capemgr.????/slots

which enables the third I2C bus and my device then was visible via i2cdetect -y -r 1 on pins P9_19 and P9_20.  Although, after doing that, you'll have an i2c1 and a i2c2 bus, so might want to check both.  But, I'm not quite sure why this works :)

In my case, I don't think there is device tree entry for the device I'm using, so I was planning on interacting with it over raw I2C.

Hope this helps,

Josh

Joshua Datko

unread,
Nov 1, 2013, 12:09:49 AM11/1/13
to beagl...@googlegroups.com, richar...@noaa.gov
Nevemind, that may be unrelated.  I just rebooted and my device enumerated fine.  I think what's confusing (me) is the I2C2 by the SRM (P9_19/20) shoes up as I2C1...

some output:

ebian@arm:~$ ls -l /sys/bus/i2c/devices/i2c-*
lrwxrwxrwx 1 root root 0 Nov  1 04:02 /sys/bus/i2c/devices/i2c-0 -> ../../../devices/ocp.2/44e0b000.i2c/i2c-0
lrwxrwxrwx 1 root root 0 Nov  1 04:02 /sys/bus/i2c/devices/i2c-1 -> ../../../devices/ocp.2/4819c000.i2c/i2c-1
debian@arm:~$ su
Password:
root@arm:/home/debian# i2cdetect -r 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] Y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Jason Kridner

unread,
Nov 1, 2013, 11:02:44 AM11/1/13
to beagl...@googlegroups.com, richar...@noaa.gov
On Fri, Nov 1, 2013 at 12:09 AM, Joshua Datko <jbd...@gmail.com> wrote:
> Nevemind, that may be unrelated. I just rebooted and my device enumerated
> fine. I think what's confusing (me) is the I2C2 by the SRM (P9_19/20) shoes
> up as I2C1...

Yeah, this is a really confusing (well-known) issue where the latest
Linux kernels assign the bus names in order of them being enumerated,
despite whatever hardware name is given to them. So, I2C0, enumerated
first, becomes, i2c0 and I2C2, enumerated second, becomes i2c1. If you
then enumerate I2C1, you'll get an i2c2. Kinda confusing, got to give
you that.

>
> some output:
>
> ebian@arm:~$ ls -l /sys/bus/i2c/devices/i2c-*
> lrwxrwxrwx 1 root root 0 Nov 1 04:02 /sys/bus/i2c/devices/i2c-0 ->
> ../../../devices/ocp.2/44e0b000.i2c/i2c-0
> lrwxrwxrwx 1 root root 0 Nov 1 04:02 /sys/bus/i2c/devices/i2c-1 ->
> ../../../devices/ocp.2/4819c000.i2c/i2c-1
> debian@arm:~$ su
> Password:
> root@arm:/home/debian# i2cdetect -r 1
> WARNING! This program can confuse your I2C bus, cause data loss and worse!
> I will probe file /dev/i2c-1 using read byte commands.
> I will probe address range 0x03-0x77.
> Continue? [Y/n] Y
> 0 1 2 3 4 5 6 7 8 9 a b c d e f
> 00: -- -- -- -- -- -- -- -- -- -- -- -- --
> 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
> 50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
> 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 70: -- -- -- -- -- -- -- --

I need hints on how the MPU6050 should be wired up or assume that I've
got a bad device. I can probably try hooking it up to something else.

smith.wi...@gmail.com

unread,
Nov 1, 2013, 12:44:59 PM11/1/13
to beagl...@googlegroups.com, richar...@noaa.gov
If you're curious as to how to figure out what I2C interface maps to which bus, take a look at this post I wrote yesterday:

clarkbr...@gmail.com

unread,
Nov 2, 2013, 11:51:04 AM11/2/13
to beagl...@googlegroups.com, richar...@noaa.gov
Jason,
I apologize for taking so long to answer. It wasn't quick to figure out which breakout board we had with the MPU6050 on it.  It is apparently a Kootek® Arduino GY-521 MPU-6050 Module from Amazon.
Itis wired:

P9_1->Gnd

P9_3->VCC

P9_19 ->SCL

P9_20 -> SDA

Your P9_19 SCL and P9_20 SDA should be fine.

Later posts suggest you can talk to you device and have shown us via W Smith  the way to straighten out which bus is which.

Clark

Mark A. Yoder

unread,
Nov 12, 2013, 3:57:54 PM11/12/13
to beagl...@googlegroups.com, richar...@noaa.gov, clarkbr...@gmail.com
Did anyone every get the inv-mpu6050 kernel driver to work?  I have the device on the i2c bus and I can read and write registers using i2cset/i2cget, but modprobe inv-mpu605 doesn't make anything appear.

--Mark

clarkbr...@gmail.com

unread,
Nov 13, 2013, 10:30:07 PM11/13/13
to beagl...@googlegroups.com, richar...@noaa.gov, clarkbr...@gmail.com
Mark,
Near as I can tell, no one has done better than just file i/o via /dev/i2c/...  This works, but doesn't seem to expose or take advantage of the Invensense kernel driver functionality.  Plus it seems to be very slow.  Jason Kridner was tackling it a couple weeks ago, but didn't report any success.  I haven't made any progress either.
Seems we are stuck. I wish someone could figure out how to ping the author at Invensense. I tried writing via thier support web page but didn't get a reply.
Clark

Mark A. Yoder

unread,
Nov 14, 2013, 4:40:35 PM11/14/13
to beagl...@googlegroups.com, richar...@noaa.gov, clarkbr...@gmail.com
It looks like someone has done a nice port to Andriod[1].  How hard would it be to port it to Angstrom?

--Mark

clarkbr...@gmail.com

unread,
Nov 16, 2013, 10:27:19 PM11/16/13
to beagl...@googlegroups.com, richar...@noaa.gov, clarkbr...@gmail.com
Mark,
I poked briefly at the reference you provided.  The write up looks very much the same as the Invensense MPU6050 driver in the Angstrom on the Black.  This seems reasonable.  The Invensense author has done a good job of getting it into the Linux tree and the various distributions have picked it up.  Apparently, the MPU 60x0 family of MEMS IMUs is widely used and popular.
The Anstrom driver reads nice.  No one here has yet to get it to load and respond.
Clark

Andrew Dai

unread,
Dec 22, 2013, 11:45:23 AM12/22/13
to beagl...@googlegroups.com, richar...@noaa.gov, clarkbr...@gmail.com
So has anyone figured out how to get the MPU6050 to respond? 
I dont know too much about how all this works but all I've done is
root@beaglebone:~# i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 
root@beaglebone:~# i2cdump -y 1 0x68
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 81 7d 00 1d 3c cd fc ae 05 44 08 5c 28 8f 6e 90    ?}.?<????D?\(?n?
10: d4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ?...............
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00    ...........@....
70: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00    .....h..........
80: 81 7d 00 1d 3c cd fc ae 05 44 08 5c 28 8f 6e 90    ?}.?<????D?\(?n?
90: d4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ?...............
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
e0: 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00    ...........@....
f0: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00    .....h..........

I cant get my board (sparkfun breakout board) to respond to anything... i2cset doesn't affect the board... did I wire something wrong?
VDD to Pin 3 (3.3V)
Gnd to Pin 1
SCL to Pin 19
SDA to Pin 20
VIO to Pin 3 (3.3) <-- I'm not quite sure what this does but I get nothing back when I disconnect it.

Any help will be greatly appreciated!

Thanks,
Andrew

clarkbr...@gmail.com

unread,
Dec 23, 2013, 4:41:43 PM12/23/13
to beagl...@googlegroups.com, richar...@noaa.gov, clarkbr...@gmail.com
Andrew,
You have made some progress.  i2cdetect can see it.  Your pin connections seem to be ok, compared to the ones posted earlier.  According to the device docs, it "will come up in sleep mode upon power up."   The SLEEP bit is apparently Bit6 in Register 0x6B.  Set it to 0 to leave the sleep mode.

Maybe that helps.

We got as far as using the MPU6050 and the MPU9150 via file I/O thru /dev/i2c.  We never got the Invensense driver to work.  It still looks like no one replying to the posts here has either.  The disadvantage of the file I/O access approach is that it seems very slow compared to the relatively few I2C bus cycles required.

Clark

Andrew Dai

unread,
Dec 26, 2013, 11:25:03 PM12/26/13
to beagl...@googlegroups.com
Setting the SLEEP bit seemed to have done the trick, everything seems to work now! (or at least at the surface)

I apologize for any beginner questions (this is my first trip into the wonderful world of embedded linux). What is the difference between the "file" approach and i2c?
I was planning on using something like the Adafruit_BBIO library (http://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black) and accessing the chip through i2c. My understanding is that that approach would be basically the same as using the command line tools (i2cdetect, i2cdump/set/get etc). Using this method, I have no use for anything driver or device tree related... correct?



You received this message because you are subscribed to a topic in the Google Groups "BeagleBoard" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/beagleboard/hqqecmOjpTU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to beagleboard...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.



--
Best Wishes,
Andrew

Joshua Datko

unread,
Dec 27, 2013, 12:49:50 AM12/27/13
to beagl...@googlegroups.com
I'm not sure I understand exactly what you are asking, but you can access the i2c bus directly through linux file descriptors (i.e. like any other normal file).  No special device drivers are needed and if you are using P_19 and P-20, it's enabled by default w/o custom device trees.

I made a blog post of resources which might help: http://datko.net/2013/11/03/bbb_i2c/


clarkbr...@gmail.com

unread,
Dec 27, 2013, 6:55:12 PM12/27/13
to beagl...@googlegroups.com
Andrew,
Doing file I/O means read and write to /dev/i2c/etc.  As you put it in your question, they are the same thing and basically the same as using the command line tools. This works out of the box.  You need to know the device registers pretty well because you will be accessing them.  Some libraries will give you nice wrappers for simple register access and some may provide higher level calls, for example, for reading all 3 gyros.
The alternative is to use the Invensense driver.  Way back up in this conversation was a description of how it should work based on documentation in the driver and the kernel source tree.  So far in this conversation, no one has made that work.  That is, the driver fails to load.  When it does load, its documentation says it will provide psuedo files that are functions under the sysfs tree /sys/bus/iio/devices.  Besides being functionally named instead of addresses, we are expecting them to be faster.  My timing tests with using file I/O via /dev/i2c shows file I/O to take significantly more time that one would expect by counting I2C bus cycles.  Some applications need faster access time than this provides.  Your application may work just fine at this speed.
Clark

Andrew Dai

unread,
Dec 28, 2013, 10:53:01 AM12/28/13
to beagl...@googlegroups.com
Okay thanks for all the help! 
I think I'm just going to get familiar with the registers and either write or find a library rather than delve too much farther into drivers and such. Maybe another day.

Thanks again for the pointers
Andrew

kd....@gmail.com

unread,
May 6, 2014, 1:42:41 PM5/6/14
to beagl...@googlegroups.com, clarkbr...@gmail.com
Knowing this discussion is old, i have to ask did you get it working? And my experience is with the bbw, not the bbb. but the i2c buss on my device is 100khz. maximum is 400khz. I was able to get the accelerometer and gyro values at a rate of 200hz without issue, which isn't the max the chip can provide, but it's more than suitable for most applications. All through accessing /dev/i2c-#. If you havent got the driver to work yet, I can send you my tiny little C program that prints the data to the shell.

On Tuesday, October 15, 2013 5:02:59 PM UTC-5, clarkbr...@gmail.com wrote:

We are using the Invensense MPU6050 IMU on I2C with Beaglebone Black (Angstrom 3.8.13). We can use I2C-tools and file I/O thru /dev/i2c but the read speed is disappointingly slow.  We only read the 3x gyros and 3x accels (each one byte at a time plus the 2 byte temperature reading) and it takes ~2msecs.  My estimate of the I2C bus cycles for a block read suggests this should take ~160 bus cycles or .38msec on a 400MHz I2C bus.

The distribution includes the Invensense driver inv-mpu6050.ko but there is no indication that reading through /dev/i2c invokes it.  This is a very popular IMU and Invensense widely distributes the driver over many Linux platforms.  The driver source includes “successful installation will create two directories under /sys/bus/iio/devices” and lists the files there (aka functions). I can never get these to show up.

I can “insmod /lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050/inv-mpu6050.ko” and “echo inv-mpu6050 0x68 > /sys/class/i2c-adapter/i2c-1/new_device”. This causes a new directory named 1-0068 to show in /sys/class/i2c-adapter/i2c-1with entries like name and modalias but no functions.  It never shows in /sys/bus/iio/devices.

What constitutes “successful installation”? 

What else is needed to get the inv-mpu6050 to expose functions in /sys/bus/iio/devices like the driver sources says?

Beaglebone Black uses bone_capemgr for exposing driver functions for many devices.  “echo inv-mpu6050 0x68 > /sys/devices/bone_capmgr.9/slots” raises the gripe “write error: no such file or directory”.  (I can successfully load the am33xx_pwm driver this way.) Is this because there is no matching DT fragment in /lib/firmware? Is the inv-mpu6050 driver supposed to be invoked thru cape manager?

clarkbr...@gmail.com

unread,
May 6, 2014, 8:16:57 PM5/6/14
to beagl...@googlegroups.com, clarkbr...@gmail.com, kd....@gmail.com
No we never got this (the Invensense driver) working.  We just stuck it out with reading /dev/i2c.  This is costing us a 20% time penalty which really really hurts.  We couldn't get anyone to take on fixing the unbelievably long read times (~1msec) on /dev/i2c either.
Some of us are hoping the up coming move to Debian from Angstrom will bring us an Invensense  driver in the distro that will somehow work.

On Tuesday, May 6, 2014 10:42:41 AM UTC-7, kd....@gmail.com wrote:
Knowing this discussion is old, i have to ask did you get it working? And my experience is with the bbw, not the bbb. but the i2c buss on my device is 100khz. maximum is 400khz. I was able to get the accelerometer and gyro values at a rate of 200hz without issue, which isn't the max the chip can provide, but it's more than suitable for most applications. All through accessing /dev/i2c-#. If you havent got the driver to work yet, I can send you my tiny little C program that prints the data to the shell.

On Tuesday, October 15, 2013 5:02:59 PM UTC-5, clarkbr...@gmail.com wrote:

We are using the Invensense MPU6050 IMU on I2C with Beaglebone Black (Angstrom 3.8.13). We can use I2C-tools and file I/O thru /dev/i2c but the read speed is disappointingly slow.  We only read the 3x gyros and 3x accels (each one byte at a time plus the 2 byte temperature reading) and it takes ~2msecs.  My estimate of the I2C bus cycles for a block read suggests this should take ~160 bus cycles or .38msec on a 400kHz I2C bus.

thomas.g...@gmail.com

unread,
May 13, 2014, 4:46:55 PM5/13/14
to beagl...@googlegroups.com, clarkbr...@gmail.com, kd....@gmail.com
Hi,
I have got a small project at home running the inv_mpu6050 driver on a 3.8.13 kernel. To get it working I had to modify the driver, so that it accepts device tree parameters, then I wrote a cape configuration for the i2c and the mpu6050 device and voila it worked. I added the driver to the kernel and then add the cape to the device tree by echoing the cape name to /sys/devices/bone_capemgr.8/slots. So then I had:

cat /sys/devices/bone_capemgr.8/slots
 0: 54:PF---
 1: 55:PF---
 2: 56:PF---
 3: 57:PF---
 4: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-MPU6050


lsmod
Module                  Size  Used by
inv_mpu6050             7868  0
g_multi                47670  0
libcomposite           14299  1 g_multi
mt7601Usta            601404  0

ls /sys/bus/iio/devices/iio:device0/
buffer         in_accel_scale  in_accel_z_raw    in_anglvel_y_raw  in_temp_offset  name         sampling_frequency_available  trigger
dev         in_accel_x_raw  in_anglvel_scale  in_anglvel_z_raw  in_temp_raw     power         scan_elements               uevent
in_accel_matrix  in_accel_y_raw  in_anglvel_x_raw  in_gyro_matrix    in_temp_scale   sampling_frequency  subsystem

cat /sys/bus/iio/devices/iio:device0/*raw
-8202
-458
11288
10
51
109
-4967

But now to the downside of it all. If I try to access the values, e.g. /sys/bus/iio/devices/iio:device0/in_accel_x_raw it takes more than 100ms?
Well I am still working on some improvements in the driver's device tree (the parameters can be negative, but the dtc version I have got can not handle unary parameters yet), but when I am finished I will commit the driver back to the community.

My work so far:
-) The Cape File:
/*
 * Copyright (C) 2014 Thomas Grazadei
 *
 * Make use of the Invensense MPU6050                   
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;
/plugin/;

/ {
        compatible = "ti,beaglebone", "ti,beaglebone-black";

        /* identification */
        part-number = "BB-MPU6050";
        version = "00A0";

        /* state the resources this cape uses */
        exclusive-use =
                /* the pin header uses */
                "P9.18",        /* i2c1_sda */
                "P9.17",        /* i2c1_scl */
                /* the hardware ip uses */
                "i2c1";

        fragment@0 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_i2c1_pins: pinmux_bb_i2c1_pins {
                                pinctrl-single,pins = <
                                        0x158 0x72      /* spi0_d1.i2c1_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
                                        0x15c 0x72      /* spi0_cs0.i2c1_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
                                >;
                        };
                };
        };

        fragment@1 {
                target = <&i2c1>;       /* i2c1 is numbered correctly */
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <&bb_i2c1_pins>;

                        /* this is the configuration part */
                        clock-frequency = <400000>;

                        #address-cells = <1>;
                        #size-cells = <0>;

                        /* add any i2c devices on the bus here */

                        mpu6050@68 {
                                compatible = "inv,mpu6050";
                                reg = <0x68>;
                                orientation = <0xff 0 0 0 1 0 0 0 0xff>;
                        };
                };
        };
};

-) and the changes in the driver:
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 37ca05b..d101a0c 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -648,6 +648,31 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st,
     return 0;
 }
 
+static struct inv_mpu6050_platform_data*
+    mpu6050_parse_dt(struct device* dev)
+{
+    struct device_node *np = dev->of_node;
+    struct inv_mpu6050_platform_data *pdata;
+
+    if (!np) {
+        dev_err(dev, "no device tree or platform data\n");
+        return ERR_PTR(-EINVAL);
+    }
+
+    pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+    if (!pdata)
+        return ERR_PTR(-ENOMEM);
+
+
+    if (of_property_read_u8_array(np, "orientation",
+        pdata->orientation, sizeof(pdata->orientation)) != 0) {
+        dev_err(dev, "no valid orientation property found\n");
+        return ERR_PTR(-EINVAL);
+    }
+
+    return pdata;
+}
+
 /**
  *  inv_mpu_probe() - probe function.
  *  @client:          i2c client.
@@ -660,6 +685,7 @@ static int inv_mpu_probe(struct i2c_client *client,
 {
     struct inv_mpu6050_state *st;
     struct iio_dev *indio_dev;
+    struct inv_mpu6050_platform_data* pdata;
     int result;
 
     if (!i2c_check_functionality(client->adapter,
@@ -675,8 +701,21 @@ static int inv_mpu_probe(struct i2c_client *client,
     }
     st = iio_priv(indio_dev);
     st->client = client;
-    st->plat_data = *(struct inv_mpu6050_platform_data
-                *)dev_get_platdata(&client->dev);
+    pdata = (struct inv_mpu6050_platform_data*)
+        dev_get_platdata(&client->dev);
+
+    if (pdata == NULL) {
+        /* check of devicetree */
+        // printk(KERN_ERR "checking device tree for parameter infos");
+        pdata = mpu6050_parse_dt(&client->dev);
+    }
+
+    if (IS_ERR(pdata)) {
+        return PTR_ERR(pdata);
+    }
+
+    st->plat_data = *pdata;
+
     /* power is turned on inside check chip type*/
     result = inv_check_and_setup_chip(st, id);
     if (result)
@@ -777,14 +816,22 @@ static const struct i2c_device_id inv_mpu_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
 
+static struct of_device_id inv_mpu6050_i2c_of_match[] = {
+    { .compatible = "inv,mpu6050", },
+    { }
+};
+
+MODULE_DEVICE_TABLE(of, inv_mpu6050_i2c_of_match);
+
 static struct i2c_driver inv_mpu_driver = {
     .probe        =    inv_mpu_probe,
     .remove        =    inv_mpu_remove,
     .id_table    =    inv_mpu_id,
     .driver = {
-        .owner    =    THIS_MODULE,
-        .name    =    "inv-mpu6050",
-        .pm     =       INV_MPU6050_PMOPS,
+        .owner        =     THIS_MODULE,
+        .name        =     "inv-mpu6050",
+        .pm         =     INV_MPU6050_PMOPS,
+        .of_match_table =     inv_mpu6050_i2c_of_match,
     },
 };
 
cheers,
gardi

thomas.g...@gmail.com

unread,
May 13, 2014, 5:10:59 PM5/13/14
to beagl...@googlegroups.com, clarkbr...@gmail.com, kd....@gmail.com
Hi,

I have got a small project at home, running the inv-mpu6050 driver. To get it to work I had to add device tree functionality to the driver and then write a cape dtc for the beaglebone. As a result I have got the following outputs:


cat /sys/devices/bone_capemgr.8/slots
 0: 54:PF---
 1: 55:PF---
 2: 56:PF---
 3: 57:PF---
 4: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-MPU6050

lsmod
Module                  Size  Used by
inv_mpu6050             7868  0
g_multi                47670  0
libcomposite           14299  1 g_multi
mt7601Usta            601404  0

ls /sys/bus/iio/devices/iio:device0/
buffer         in_accel_scale  in_accel_z_raw    in_anglvel_y_raw  in_temp_offset  name         sampling_frequency_available  trigger
dev         in_accel_x_raw  in_anglvel_scale  in_anglvel_z_raw  in_temp_raw     power         scan_elements               uevent
in_accel_matrix  in_accel_y_raw  in_anglvel_x_raw  in_gyro_matrix    in_temp_scale   sampling_frequency  subsystem

cat /sys/bus/iio/devices/iio:device0/*raw
-8202
-458
11288
10
51
109
-4967

But now to the downside. It takes about100ms to read one value e.g. /sys/bus/iio/devices/iio:device0/in_accel_x_raw ?!

I am still working on the device tree part of the driver, as the configuration should be able to deal with negative values, but my current dtc does not support the unary operator yet. That is fixed in a later version. I will have a look at that when I find some time. When it is finished I would like to give the driver back to the community.

For now my work has the current state:
-) MPU6050 cape:
/*
 * Copyright (C) 2014 Thomas Graziadei
 *
 * Make use of the Invensens MPU6050
            clock-frequency = <100000>;   

            #address-cells = <1>;
            #size-cells = <0>;

            /* add any i2c devices on the bus here */

            mpu6050@68 {
                compatible = "inv,mpu6050";
                reg = <0x68>;
                orientation = <1 0 0 0 1 0 0 0 1>;
            };
        };
    };
};


-) driver patch:

bruce....@gmail.com

unread,
Sep 15, 2014, 7:34:19 AM9/15/14
to beagl...@googlegroups.com, clarkbr...@gmail.com, kd....@gmail.com, thomas.g...@gmail.com
Hi

Also been struggling to get Invensense driver to work....not very impressed with Invensense to be honest. If you login to their support forum, there is no mention of MPU9250 Linux kernel drivers.....I found the tegra stuff, emailed Invensense and asked them where they publish their code.....they don't.

Rather then release a unified driver for 3.4 (i2c &spi) and 3.10+ (i2c & spi) ....they rather efforts and struggle be duplicated by every user of their component....this is very advanced and progressive thinking .....the head of software development must be an absolute genius, no wonder their products are so easy to integrate.

Invense replied to my email with this link:

*So I'm guessing with the endless array of 2012 versions.....this is what they suggested....no idea 


I have yet to find an working Invensense driver that natively supports MPU9250 for the 3.10+ kernel....and absolutely nothing that supports Linux & SPI

Hoping bosch will come to the rescue and offer real linux support for this little guy:

Invensense may have some nice components....but they're worthless without quality drivers. 

neo

unread,
Sep 17, 2014, 11:15:31 PM9/17/14
to beagl...@googlegroups.com, clarkbr...@gmail.com, kd....@gmail.com, thomas.g...@gmail.com, bruce....@gmail.com

samuel....@gmail.com

unread,
Oct 1, 2014, 9:22:37 AM10/1/14