Optional interfaces (I2C, I2S, SPI) and Device Tree


123 posts   Page 1 of 5   1, 2, 3, 4, 5
by PhilE » Sun Feb 01, 2015 8:30 pm
The new 3.18 kernels (available now from rpi-update and future apt-get update and NOOBS releases) will use Device Tree for hardware configuration by default. You can read an explanation why this change has been made, and what the implications are, here, but the short version is:

If you want to use the respective header pins for I2C, SPI, I2S instead of GPIO then you now need to enable those interfaces by adding one (or more) of the following to your /boot/config.txt:
Code: Select all
dtparam=i2c_arm=on
dtparam=spi=on
dtparam=i2s=on

Multiple parameters can be set in one line:
Code: Select all
dtparam=i2c_arm=on,spi=on

The up-side is that you no longer need to blacklist the drivers of interfaces and devices that you don't want.

The new raspi-config can set these parameters for you, and even disable Device Tree should you feel the need.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by McPeppr » Tue Feb 03, 2015 1:06 am
Thank you so much to explain the change. I was looking for a solution the whole day after I updated raspbian and could not go on with my project. Here's were I wrote about my trouble in my fresh raspi-blog.
https://mcpeppr.wordpress.com/2015/02/02/spidev-is-broken/
Posts: 1
Joined: Thu Jul 03, 2014 4:00 pm
by fbuster » Tue Feb 03, 2015 7:47 pm
Posts: 60
Joined: Mon May 05, 2014 8:31 pm
by DirkS » Tue Feb 03, 2015 11:33 pm
fbuster wrote:1-wire is also affected

This post also helped me to get it back working:

http://raspberrypi.stackexchange.com/questions/27073/firmware-3-18-x-breaks-i2c-spi-audio-lirc-1-wire-e-g-dev-i2c-1-no-such-f

I think it's better to use 'local; information; this will normally be updated if there are any changes.
See link in top post of this topic (or click here)
Posts: 6781
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex, UK
by capnm » Fri Feb 06, 2015 11:48 am
In the case somebody faces the same problem:
After an apt-get dist-upgrade all my apps stopped working with a gpio permissions problems.
I guess that the created paths in /sys/class/gpio/* are now symlinks and the current udev rules are not working as intended.
I fixed that by creating a new udev rule file /etc/udev/rules.d/10-gpio.rules
Code: Select all
# File /etc/udev/rules.d/10-gpio.rules
#
# udev debugging cheat sheet:
#
# https://www.kernel.org/pub/linux/utils/kernel/hotplug/udev/udev.html
# udev paths /etc/udev/rules.d/ /lib/udev/rules.d/
# pkill udevd && udevd --debug
# udevadm control --log-priority debug && cat /var/log/syslog
# udevadm monitor --env
# sys path /sys/class/gpio
#
# Note: you must be in the gpio group to have access to the gpio pins
#

SUBSYSTEM=="gpio", KERNEL!="gpio[0-9]*", ACTION=="add", PROGRAM="/bin/bash -c 'chown -R root:gpio $sys/class/gpio ; chmod 220 $sys/class/gpio/{export,unexport}'"

SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/bash -c 'chmod -f 755 $sys$devpath ; chmod -f 660 $sys$devpath/{active_low,direction,edge,uevent,value} ; chown -Rf root:gpio $sys/$devpath'"

and then I disabled all useless rules to avoid unnecessary udev slowdown:
fgrep -R gpio /lib/udev/rules.d/
Code: Select all
mv /lib/udev/rules.d/60-python3-pifacecommon.rules  /lib/udev/rules.d/60-python3-pifacecommon.rules--
mv /lib/udev/rules.d/60-python-pifacecommon.rules /lib/udev/rules.d/60-python-pifacecommon.rules--

(I never used the piface so it may need some additional tweaks for piface.)
Last edited by capnm on Mon Feb 09, 2015 9:10 am, edited 1 time in total.
Martin Capitanio http://capitanio.org
Posts: 3
Joined: Fri Feb 06, 2015 11:03 am
Location: Frankfurt, Germany
by mikronauts » Sun Feb 08, 2015 3:40 am
my /boot/config.txt has the following:

dtparam=spi=on
dtparam=i2c_arm=on

and I can use MCP23017's without any problems, so I think i2c_arm must be equivalent to i2c1, correct?
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi
User avatar
Posts: 2581
Joined: Sat Jan 05, 2013 7:28 pm
by PhilE » Sun Feb 08, 2015 8:07 am
Yes, correct, unless you have an early Pi in which case it is equivalent to i2c0.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by mikronauts » Sun Feb 08, 2015 3:41 pm
Thank you!

PhilE wrote:Yes, correct, unless you have an early Pi in which case it is equivalent to i2c0.
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi
User avatar
Posts: 2581
Joined: Sat Jan 05, 2013 7:28 pm
by hegylako1594 » Sun Feb 08, 2015 4:03 pm
Dear Man (PhilE),
your post is perfect! Thank you very much, you helped me a lot! :)
Zoltan


PhilE wrote:The new 3.18 kernels (available now from rpi-update and future apt-get update and NOOBS releases) will use Device Tree for hardware configuration by default. You can read an explanation why this change has been made, and what the implications are, here, but the short version is:

If you want to use the respective header pins for I2C, SPI, I2S instead of GPIO then you now need to enable those interfaces by adding one (or more) of the following to your /boot/config.txt:
Code: Select all
dtparam=i2c=on
dtparam=spi=on
dtparam=i2s=on

Multiple parameters can be set in one line:
Code: Select all
dtparam=i2c=on,spi=on

The up-side is that you no longer need to blacklist the drivers of interfaces and devices that you don't want.

The new raspi-config can set these parameters for you, and even disable Device Tree should you feel the need.
Posts: 4
Joined: Wed Jan 07, 2015 12:30 pm
Location: Hungary
by PhilE » Sun Feb 08, 2015 4:07 pm
You're welcome. I think if I am going to "break" things by making changes, then it is only fair that I tell people how to "fix" them.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by tonygo2 » Tue Feb 10, 2015 2:11 pm
I've got a DS18D20 thermometer on a Keys breakout board which has a pull up resistor on the board. The data line is on GPIO pin #4. This was working before the upgrade.
I understand that I have to add a line to /boot.config.txt but am not sure which one I need:
dtoverlay=w1-gpio-pullup,gpiopin=x,pullup=y
or
dtoverlay=w1-gpio-pullup,gpiopin=x

I'm guessing x=4 but if I need the first example what is y?
Posts: 83
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK
by PhilE » Tue Feb 10, 2015 2:22 pm
Yes, the overuse of the word "pullup" is confusing, but I wanted to keep the parameter names the same as those of the module parameters.

Here's what the README says:
Code: Select all
File:   w1-gpio-overlay.dtb
Info:   Configures the w1-gpio Onewire interface module.
        Use this overlay if you *don't* need a pin to drive an external pullup.
Load:   dtoverlay=w1-gpio,<param>=<val>
Params: gpiopin                  GPIO pin for I/O (default "4")

        pullup                   Non-zero, "on", or "y" to enable the parasitic
                                 power (2-wire, power-on-data) feature


File:   w1-gpio-pullup-overlay.dtb
Info:   Configures the w1-gpio Onewire interface module.
        Use this overlay if you *do* need a pin to drive an external pullup.
Load:   dtoverlay=w1-gpio-pullup,<param>=<val>,...
Params: gpiopin                  GPIO pin for I/O (default "4")

        pullup                   Non-zero, "on", or "y" to enable the parasitic
                                 power (2-wire, power-on-data) feature

        extpullup                GPIO pin for external pullup (default "5")

How does this apply in your case? Well, although you have a pullup resistor, I doubt you are using a dedicated GPIO pin to enable the pullup, so you don't need the "-pullup" variant.

If you are using the parasitic power mode (where the host delivers power over the data line), and you would know this because your /etc/modules or /etc/modprobe.d/<something>.conf would include "pullup=1", then you would need to add ",pullup=1" or ",pullup=on".

In summary, I think you need either:
Code: Select all
dtoverlay=w1-gpio,gpiopin=4

or possibly
Code: Select all
dtoverlay=w1-gpio,gpiopin=4,pullup=1

I suggest you try the first version, and if your sensor is reporting a steady 85C then switch to the second instead.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by tonygo2 » Tue Feb 10, 2015 2:59 pm
Wow! - what a quick reply.
Thank you very much. The first, and shorter one, worked perfectly.
One other point: can I use gpio pin #21 instead of #4? The tutorial I used specified #4 so I used that but #21 would be more useful.
Posts: 83
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK
by PhilE » Tue Feb 10, 2015 3:02 pm
It would potentially clash with an I2S device (usually audio devices) on a more recent Pi, but if that isn't a concern then go ahead and use 21.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by tonygo2 » Tue Feb 10, 2015 3:04 pm
Thanks, I'll leave it were it is.
Posts: 83
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK
by iinnovations » Mon Feb 16, 2015 7:56 am
Can you detail the exact config changes made by raspi-config when each of the interfaces is enabled? I typically script these in an initscript, and I'd just like to ensure that I'm replicating the same configuration changes made by raspi-config. Even better, if the raspi-config changes could be made by command line with something like raspi-config -i2c enable, that would be super.

Thanks,
C
CuPID Controls :: Open Source browser-based sensor and device control
interfaceinnovations.org/cupidcontrols.html
cupidcontrols.com
User avatar
Posts: 621
Joined: Thu Jun 06, 2013 5:17 pm
by PhilE » Mon Feb 16, 2015 8:54 am
i2c:
Code: Select all
    sed $CONFIG -i -r -e "s/^((device_tree_param|dtparam)=([^,]*,)*i2c(_arm)?)(=[^,]*)?/\1=$SETTING/"
    if ! grep -q -E "^(device_tree_param|dtparam)=([^,]*,)*i2c(_arm)?=[^,]*" $CONFIG; then
      printf "dtparam=i2c_arm=$SETTING\n" >> $CONFIG
    fi

This is gobbledygook for:
    * Search /boot/config.txt for any existing dtparam line which sets the "i2c_arm" parameter, and ensure it is set to "on" or "off" as appropriate.
    * If no such dtparam line exists, add one at the end.
In other words, if the interface is to be enabled then /boot/config.txt must contain:
Code: Select all
dtparam=i2c_arm=on

Disabling involves replacing the "on" with an "off", or deleting the assignment altogether.

spi:
Code: Select all
    sed $CONFIG -i -r -e "s/^((device_tree_param|dtparam)=([^,]*,)*spi)(=[^,]*)?/\1=$SETTING/"
    if ! grep -q -E "^(device_tree_param|dtparam)=([^,]*,)*spi=[^,]*" $CONFIG; then
      printf "dtparam=spi=$SETTING\n" >> $CONFIG
    fi

As above, but substitute "spi" for "i2c_arm".

Control of the module loading for both interfaces works as before.

Is that clear enough?
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by iinnovations » Mon Feb 16, 2015 9:05 am
So lovely to see sed.

So to be clear, the only modifications necessary are in /boot/config.txt ? No modprobe or otherwise?

If this is the case, then that's all I need.

Thanks,
C
CuPID Controls :: Open Source browser-based sensor and device control
interfaceinnovations.org/cupidcontrols.html
cupidcontrols.com
User avatar
Posts: 621
Joined: Thu Jun 06, 2013 5:17 pm
by PhilE » Mon Feb 16, 2015 9:20 am
That is all you need provided the driver modules aren't blacklisted. If Device Tree is enabled then you shouldn't normally have any need to stop a module from loading automatically, but that didn't used to be the case. So look in /etc/modprobe.d/raspi-blacklist.conf (if it exists) and comment out any references to i2c-bcm2708 and spi-bcm2708 (or everything...)

It occurs to me that I didn't mention the need to reboot before changes in config.txt take effect. If you were looking to toggle the interfaces while the system is running then you would need a different approach - leave the device node enabled (e.g. i2c_arm=on) and then use the blacklist to control the module loading. You can then use modprobe/rmmod to dynamically enable or disable the interface. In future I hope to enable dynamic device tree manipulation, but that is some way off.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by iinnovations » Mon Feb 16, 2015 9:25 am
That is fine. I don't require any dynamic loading. I will drop an empty blacklist and copy over a desired config.

Thanks for the quick concise response.

C
CuPID Controls :: Open Source browser-based sensor and device control
interfaceinnovations.org/cupidcontrols.html
cupidcontrols.com
User avatar
Posts: 621
Joined: Thu Jun 06, 2013 5:17 pm
by iinnovations » Thu Feb 19, 2015 4:17 am
This does not seem to work. I add the /boot/config entries, no dice. I enable via raspi-config, including enabling the kernel module, no dice. I have to go to /etc/modules and add i2c-dev. Shouldn't raspi-config add it?

Linux cupid 3.18.7-v7+ #755 SMP PREEMPT Thu Feb 12 17:20:48 GMT 2015 armv7l GNU/Linux

C
CuPID Controls :: Open Source browser-based sensor and device control
interfaceinnovations.org/cupidcontrols.html
cupidcontrols.com
User avatar
Posts: 621
Joined: Thu Jun 06, 2013 5:17 pm
by iinnovations » Thu Feb 19, 2015 5:23 am
On a similar note, I can't find a good tutorial for setting up the i2c EEPROM for HATs. Looks like it requires enabling i2c-0 for ID_SD and ID_SC. Links appreciated.

<< edit >>

I had to add dtparam=i2c_vc=on to boot/config.txt. This worked on both a B+ and also a Pi 2. It's a bit kooky that the memory doesn't show up using i2cdetect, but the eepromutils script will detect and read/write it. Good thing my google-fu is strong, because it was sure tripping me out that I could get the EEPROM to show as address 50 on i2c1, but not i2c-0.

Now on to the important part -- how does a user or application access the HAT data?

C
CuPID Controls :: Open Source browser-based sensor and device control
interfaceinnovations.org/cupidcontrols.html
cupidcontrols.com
User avatar
Posts: 621
Joined: Thu Jun 06, 2013 5:17 pm
by raspiprojekt » Fri Feb 27, 2015 9:28 am
Found out that I2C definitivly not working with device tree on raspian image from 02/16. SPI, 1wire and I2S seems to work fine. For using I2C you must disable DT and load modules (not only for I2C, SPI,1wire also). Is that a know issue?
Jörg von raspiprojekt.de - Ihr braucht es, ich besorg es!
Posts: 6
Joined: Tue Oct 22, 2013 12:24 pm
by PhilE » Fri Feb 27, 2015 9:31 am
You must enable the i2c interface using:
Code: Select all
dtparam=i2c_arm=on

AND load the i2c-dev module, either manually or by adding it to /etc/modules.

If you have done this and it isn't working then please describe what you do and what you observe.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge
by PhilE » Fri Feb 27, 2015 9:33 am
Also check that the i2c_bcm2708 module isn't blacklisted (in /etc/modprobe.d/raspi-blacklist.conf). Alternatively, use raspi-config to make the necessary changes for you (Advanced Options -> I2C -> Yes, Yes).
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1124
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge