ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Enable SPI and I2C with device tree

Wed Jun 17, 2015 1:52 pm

Hi,

I am using device tree with kernel 3.18.14+ and on a RaspberryPi B I used to add the following lines to /boot/config.txt in order to enable the SPI and I2C interfaces:

Code: Select all

dtparam=i2c_arm=on
dtparam=spi=on
On the Compute module, this doesn't work any more. The SPI (spi-bcm2835) and I2C (i2c_dev) drivers are not loaded automatically. But even if I load them manually, the related device files are not created in /dev.

Is there something else I have to do to make this work on the Compute module? I have read all the available documentation on device tree but it got me even more confused. Do I have to create my own dtb file?

It would be great if someone could help me out here,
Ondrej
The Telegea.org project: https://www.telegea.org

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

Re: Enable SPI and I2C with device tree

Wed Jun 17, 2015 2:50 pm

Should not SPI be spi_bcm2708. Or have you got an experimental kernel?

Device tree will load the i2c_bcm2708 module. You still need to manually load the i2c_dev module.

ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Wed Jun 17, 2015 3:20 pm

Hi Joan,

I am using the stock RaspberryPi Kernel installed with rpi-update:

Code: Select all

# uname -a
Linux geopi 3.18.14+ #794 PREEMPT Sun Jun 7 12:02:04 BST 2015 armv6l GNU/Linux
This is my /boot/config.txt:

Code: Select all

gpu_mem=16
dtparam=i2c_arm=on
dtparam=spi=on
When the system starts there are no SPI or I2C drivers loaded:

Code: Select all

# lsmod
Module                  Size  Used by
ipv6                  352305  24 
cfg80211              462846  0 
rfkill                 22347  2 cfg80211
snd_bcm2835            20818  0 
snd_pcm                90778  1 snd_bcm2835
snd_timer              23007  1 snd_pcm
snd                    66325  3 snd_bcm2835,snd_timer,snd_pcm
8192cu                569561  0 
uio_pdrv_genirq         3666  0 
uio                     9897  1 uio_pdrv_genirq
I try to load the drivers manually (spi_bcm2708 does not load):

Code: Select all

# modprobe spi_bcm2708
modprobe: ERROR: could not insert 'spi_bcm2708': No such device
# modprobe spi_bcm2835
# modprobe  i2c_bcm2708
Now they are loaded:

Code: Select all

# lsmod
Module                  Size  Used by
spi_bcm2835             4562  0 
i2c_bcm2708             6216  0 
ipv6                  352305  24 
cfg80211              462846  0 
rfkill                 22347  2 cfg80211
snd_bcm2835            20818  0 
snd_pcm                90778  1 snd_bcm2835
snd_timer              23007  1 snd_pcm
snd                    66325  3 snd_bcm2835,snd_timer,snd_pcm
8192cu                569561  0 
uio_pdrv_genirq         3666  0 
uio                     9897  1 uio_pdrv_genirq
But the alternative functions are not selected (pins 0,1 for I2C and pins 7,8,9,10 for SPI):

Code: Select all

gpio readall
+-----+------+-------+      +-----+------+-------+
| Pin | Mode | Value |      | Pin | Mode | Value |
+-----+------+-------+      +-----+------+-------+
|   0 | IN   | High  |      |  28 | IN   | Low   |
|   1 | IN   | High  |      |  29 | IN   | Low   |
|   2 | IN   | High  |      |  30 | IN   | Low   |
|   3 | IN   | High  |      |  31 | IN   | Low   |
|   4 | IN   | High  |      |  32 | IN   | Low   |
|   5 | IN   | High  |      |  33 | IN   | Low   |
|   6 | IN   | High  |      |  34 | IN   | High  |
|   7 | IN   | High  |      |  35 | IN   | High  |
|   8 | IN   | High  |      |  36 | IN   | High  |
|   9 | IN   | Low   |      |  37 | IN   | High  |
|  10 | IN   | Low   |      |  38 | IN   | Low   |
|  11 | IN   | Low   |      |  39 | IN   | Low   |
|  12 | IN   | Low   |      |  40 | IN   | Low   |
|  13 | IN   | Low   |      |  41 | IN   | Low   |
|  14 | ALT0 | High  |      |  42 | IN   | Low   |
|  15 | ALT0 | High  |      |  43 | IN   | Low   |
|  16 | IN   | Low   |      |  44 | IN   | Low   |
|  17 | IN   | Low   |      |  45 | IN   | Low   |
|  18 | IN   | Low   |      |  46 | IN   | High  |
|  19 | IN   | Low   |      |  47 | OUT  | Low   |
|  20 | IN   | Low   |      |  48 | ALT3 | Low   |
|  21 | IN   | Low   |      |  49 | ALT3 | High  |
|  22 | IN   | Low   |      |  50 | ALT3 | High  |
|  23 | IN   | Low   |      |  51 | ALT3 | High  |
|  24 | IN   | Low   |      |  52 | IN   | High  |
|  25 | IN   | Low   |      |  53 | IN   | High  |
|  26 | IN   | Low   |      |  54 | IN   | Low   |
|  27 | IN   | Low   |      |  55 | IN   | Low   |
+-----+------+-------+      +-----+------+-------+
What am I missing???
The Telegea.org project: https://www.telegea.org

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

Re: Enable SPI and I2C with device tree

Wed Jun 17, 2015 3:34 pm

For I2C you still need to modprobe i2c_dev.

Are you sure spi_bcm2835 is the correct module? As far as I know it does not work on the Pi. I do not understand why spi_bcm2708 is not found.

It seems like you will need to wait for someone who actaully uses the compute module.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Wed Jun 17, 2015 4:00 pm

Yes, that is expected behaviour for a Compute Module. The thinking is that because of the increased flexibility over pin use, you pretty much have to create your own .dtb file (or overlay) to make use of a CM, so the supplied files are virtually a blank slate. As a result, there is no "spi" parameter defined for the CM.

However, having discussed this with James, there is no harm in having the old parameters in there, since they don't doing anything unless enabled. I will reinstate the spi, i2c and i2s parameters in the current kernel trees (3.18 and 4.0).

Note that these parameters will enable the interfaces in the standard b-plus locations:

Code: Select all

	spi0_pins: spi0_pins {
		brcm,pins = <7 8 9 10 11>;
		brcm,function = <4>; /* alt0 */
	};

	i2c0_pins: i2c0 {
		brcm,pins = <0 1>;
		brcm,function = <4>;
	};

	i2c1_pins: i2c1 {
		brcm,pins = <2 3>;
		brcm,function = <4>;
	};

	i2s_pins: i2s {
		brcm,pins = <18 19 20 21>;
		brcm,function = <4>; /* alt0 */
	};
If you want something else you will have to hack your own dtb:

ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Wed Jun 17, 2015 4:24 pm

Thanks PhilE, I was actually affraid that some dtb file modification was needed :?

So if I understand this correctly, I will need to generate a new bcm2708-rpi-cm.dtb file by modifying these source files:
https://github.com/raspberrypi/linux/bl ... rpi-cm.dts
https://github.com/raspberrypi/linux/bl ... pi-cm.dtsi

It looks that I could basically just reuse the B+ dts file from here (and make any changes later, if needed):
https://github.com/raspberrypi/linux/bl ... -rpi-b.dts

Just wanted confirmation before I start messing with these things.

Ondrej
The Telegea.org project: https://www.telegea.org

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Wed Jun 17, 2015 4:37 pm

I've just pushed my patches to rpi-3.18.y and rpi-4.0.y. They should do what you want.

ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 8:10 am

PhilE wrote:I've just pushed my patches to rpi-3.18.y and rpi-4.0.y. They should do what you want.
Thanks for the quick fix.
I compiled a new bcm2708-rpi-cm.dtb based on these changes and now the spi_bcm2708 driver is loaded automatically and the SPI devices spidev0.0 and spidev0.1 are created correctly.
However I2C is still not working. I can load i2c_bcm2708 and i2c_dev manually without error but no devices are created.

Any idea?
The Telegea.org project: https://www.telegea.org

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 8:13 am

Have you done anything to enable them? Try something like:

Code: Select all

dtparam=i2c0=on
dtparam=i2c1=on

ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 8:39 am

Yes, that was it. It's working now. :D
I had this in the config.txt:

Code: Select all

dtparam=i2c_arm=on
which is from the official documentation. But things seem to be a little different on the Compute module. OK, another lesson learned.

Thanks for your support.
Ondrej
The Telegea.org project: https://www.telegea.org

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 8:43 am

The ownership of the I2C interfaces is less clear on the CM, since there may be two cameras or no cameras. It is better to stick to the numeric values.

ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 9:40 am

Oooh, I have another question. The I2C ports are set up for pins 0,1 and 2,3 as I can see in the dts file:

Code: Select all

        i2c0_pins: i2c0 {
                brcm,pins = <0 1>;
                brcm,function = <4>;
        };

        i2c1_pins: i2c1 {
                brcm,pins = <2 3>;
                brcm,function = <4>;
        };
How would I modify this to make i2c0 also available on pins 28,29 (alt0) and i2c1 on pins 44,45 (alt2) ?
The Telegea.org project: https://www.telegea.org

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 10:02 am

You can't make them available in multiple places at once, or it the interface don't work. If this isn't what you meant, tell me how you would expect to switch between the alternatives?

ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 10:25 am

Well, from the table of GPIO pins I can see that e.g. SDA0 signal is connected three GPIO pins: GPIO0 (alt0 function), GPIO28 (alt0 function) and GPIO44 (alt1 function).
So let's say I would like to physically connect a device A to GPIO0 and device B to GPIO44. By selecting alt0 function on GPIO0 and alt1 function on GPIO44, both devices should be connected to the I2C0 bus. The devices have different I2C addresses, of course.

So you are saying that this setup is not possible ?
The Telegea.org project: https://www.telegea.org

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 10:40 am

Yes, that's what I'm saying - if you have the same function enabled on multiple pins (or groups of pins) then it won't work.

But, don't forget that I2C is a bus - you can connect devices A and B to any single group of pins (0 & 1, 28 & 29, 44 & 45).
Or you can connect A to I2C0 and B to I2C1.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 9499
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 11:07 am

Just to extend what Phil has said, it is possible to dynamically mux the I2C function around as long as you only enable one set of pins at a time.
That is how the GPU code gets two cameras with the same I2C address to work using only one I2C peripheral.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 11:15 am

Yes, that's true, but it's not clear how one would control that in a clean way from the host - probably some pinmux magic - so I didn't want to dangle that carrot.

ondrej1024
Posts: 171
Joined: Thu Dec 05, 2013 3:09 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 11:49 am

OK, looks like I had a wrong understanding of this. I always thought that the function muxing on the GPIO pins is a great feature which provides flexibility for the devices that are connected because the pin functions can be set by the software, instead of using jumpers.

If I connect device A and device B to different pins, then I have the possibility to use them on the same bus (by selecting the corresponding alternative functions) or control them completely separately by selecting the normal GPIO functions. If I connect both devices to the same pin, I can use them only in bus mode.

That said, I still don't fully understand this. If device tree enables i2c0 on pins GPIO0,1 why does i2c0 not become available also on pins GPIO44,45 when I select their alternative functions manually (using the raspi-gpio tool). Isn't there a physical connection between the processors i2c interface and the mux of every GPIO pin where this function is available?
The Telegea.org project: https://www.telegea.org

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 9499
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Enable SPI and I2C with device tree

Thu Jun 18, 2015 1:58 pm

ondrej1024 wrote:OK, looks like I had a wrong understanding of this. I always thought that the function muxing on the GPIO pins is a great feature which provides flexibility for the devices that are connected because the pin functions can be set by the software, instead of using jumpers.
That is correct as a first approximation.
ondrej1024 wrote:That said, I still don't fully understand this. If device tree enables i2c0 on pins GPIO0,1 why does i2c0 not become available also on pins GPIO44,45 when I select their alternative functions manually (using the raspi-gpio tool). Isn't there a physical connection between the processors i2c interface and the mux of every GPIO pin where this function is available?
Don't ask me exactly what goes on in the hardware to restrict that, but memory says you lose all receive paths if you do that. It does NOT just mux together all the receive lines from the multiple GPIOs. At a guess it's so as to avoid having to know which logical state is active - for I2C pulled to ground is the active state, so you'd want a logical AND to combine them. For an active high line, you'd want a logical OR between them all.
Having to add that sort of differentiation into a simple mux block starts getting grotty when there's no good reason for it.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

User avatar
raspitrick
Posts: 30
Joined: Fri Jun 07, 2013 12:49 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Sat Jun 20, 2015 10:04 am

I'm also having trouble enabling i2c-1 on the Compute Module.
Following the previous discussion I edited my /boot/config.txt to include:

dtparam=i2c_arm=on
dtparam=i2c1=on

After bootup, neither i2c_bcm2708 gets loaded, nor /dev/i2c-1 gets created, nor are GPIO2/3 set to their ALT0 functions as raspi-gpio reports:

BANK0 (GPIO 0 to 27):
GPIO 00: level=1 fsel=0 alt= func=INPUT
GPIO 01: level=1 fsel=0 alt= func=INPUT
GPIO 02: level=1 fsel=0 alt= func=INPUT
GPIO 03: level=0 fsel=0 alt= func=INPUT

Manually loading i2c_bcm2708 and i2c_dev and setting GPIO2/3 to their ALT0 functions with raspi-gpio changes nothing (modules load without error, but /dev/i2c-1 is not created, i2cdetect -y 1 fails).

I'm using 2015-05-05-raspbian-wheezy.img with stock kernel 3.18.14+.

Any ideas?
RasPiGNSS - a precision GPS+GLONASS+SBAS expansion board (http://raspignss.tech)

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Sat Jun 20, 2015 10:14 am

This feature has only just been enabled in the firmware. If you rpi-update you should find that the i2c0 and i2c1 dtparams work. Note that i2c_vc and i2c_arm won't work, as the ownership of the I2C ports is flexible with the CM.

User avatar
raspitrick
Posts: 30
Joined: Fri Jun 07, 2013 12:49 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Sat Jun 20, 2015 5:14 pm

Thanks, after rpi-update dtparam=i2c1=on in /boot/config.txt works; i2c_bcm2708 gets loaded automatically, and after loading i2c-dev I can see /dev/i2c1.
Also, raspi-gpio reports GPIO2/3 as set to their ALT0 functions SDA1/SCL1.

However, i2cdetect -y 1 still detects no i2c devices on my bus - must be a hardware problem then:

Code: Select all

# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
RasPiGNSS - a precision GPS+GLONASS+SBAS expansion board (http://raspignss.tech)

User avatar
raspitrick
Posts: 30
Joined: Fri Jun 07, 2013 12:49 pm
Contact: Website

Re: Enable SPI and I2C with device tree

Mon Jun 22, 2015 7:51 am

It was the i2c pullups; now i2cdetect -y 1 sees my devices:

Code: Select all

# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- 5d -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
From what I gathered it seems that i2c0 is dedicated to the VC for camera usage etc. - is there as possibility (probably via a custom dt-blob.bin) to make it available for the ARM, if there's no camera needed in the system?
RasPiGNSS - a precision GPS+GLONASS+SBAS expansion board (http://raspignss.tech)

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Enable SPI and I2C with device tree

Mon Jun 22, 2015 8:00 am

I'm happy you got it working.

The assignment of the I2C ports is configurable on the Compute Module - there is no fixed 0 -> VC, 1 -> ARM mapping. If you want to run two cameras (for example) then you might let VC have both I2C ports, but with no cameras you might want the ARM to use both. That's what I was getting at when I wrote:
Note that i2c_vc and i2c_arm won't work, as the ownership of the I2C ports is flexible with the CM.
This is the source of the CM section in the default dt-blob.bin:

Code: Select all

      pins_cm {
         pin_config {
            pin@default {
               polarity = "active_high";
               termination = "pull_down";
               startup_state = "inactive";
               function = "input";
            }; // pin
            pin@p14 { function = "uart0";  termination = "no_pulling";    }; // TX uart0
            pin@p15 { function = "uart0";  termination = "pull_up"; }; // RX uart0
            pin@p48 { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CLK
            pin@p49 { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CMD
            pin@p50 { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D0
            pin@p51 { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D1
            pin@p52 { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D2
            pin@p53 { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D3
         }; // pin_config

         pin_defines {
         }; // pin_defines
Aside from the SD/MMC interface and the UART (and that may be removed in future) there are no static pin assignments, and both I2C ports are available to the ARM.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 9499
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Enable SPI and I2C with device tree

Mon Jun 22, 2015 10:54 am

PhilE wrote:If you want to run two cameras (for example) then you might let VC have both I2C ports, but with no cameras you might want the ARM to use both.
Minor correction: You can use both I2C ports for the 2 cameras, but you don't have to. You can set both cameras to use the same I2C peripheral (normally 0), but with one on pins 0/1, and one on pins 28/29. The GPU firmware sets the relevant pin muxing to I2C mode only when it is told that it is going to communicate with that device, and sets it back to input immediately afterwards. That's covered in the docs - https://www.raspberrypi.org/documentati ... -camera.md

(If running in stereoscopic mode, then I don't believe there is any gain in running them from independent ports, as they are both setup from the same thread and hence serialised. If running them independently, then it does avoid the two camera systems blocking each other on I2C traffic)

If you're using a Compute Module and haven't done any of the camera dt-blob mods covered in those docs, then the GPU will never touch I2C-0, so you are free to use it for your own purposes (as Phil says).
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Return to “Compute Module”