Linux device drivers for Rapberry Pi on-board I/O


98 posts   Page 3 of 4   1, 2, 3, 4
by Frank Buss » Wed May 09, 2012 9:30 pm
GadgetUK said:


Frank, great work.

No luck for me here with the .config file :(

Pi boots, but no sign of /dev/i2c entries.



Did you install it with all modules to the right place? I've used this manual:

http://elinux.org/RPi_Kernel_Compilation

What says "dmesg"? There should be these two lines:

i2c-gpio i2c-gpio.0: using pins 0 (SDA) and 1 (SCL)
i2c-gpio i2c-gpio.1: using pins 2 (SDA) and 3 (SCL)

Do you use the Debian image? Maybe some other images don't use udev, which would mean that you have to create the device nodes yourself:

mknod /dev/i2c-0 c 89 0
mknod /dev/i2c-1 c 89 1

This is my kernel:

http://www.frank-buss.de/tmp/kernel.img
User avatar
Posts: 92
Joined: Fri Jan 06, 2012 4:39 pm
by GadgetUK » Wed May 09, 2012 10:11 pm
Frank, thanks works, as did an image from selisinork.

Looks like I was missing the patches you'd applied.

Need to get to grips with git etc.
Posts: 42
Joined: Thu Jan 19, 2012 6:02 pm
by pygmy_giant » Wed May 09, 2012 10:22 pm
God bless you boffins – there is a debate on another thread about whether linux + I2C gyros/accellerometers could handle balancing a robot on 2 wheels. I for one am following your progress with interest – you are doing valuabe work…
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by Frank Buss » Thu May 10, 2012 5:32 am
csoutreach said:

Great to hear progress on I2C. I've asked a similar question about pin allocation for the SPI driver. http://www.raspberrypi.org/for.....-3/#p73509
I suggested passing in config arguments at boot time which enable which drivers/pin configs are used. I think this is what beagleboards do -- in fact I think they probe the I2C bus at boot to decide.

I also started discussing pinctrl/pinmux from the kernel which deals with this sort of thing, and can be exposed to userspace through appropriate /sys/.... or somewhere in device tree.

Thoughts?


pinctrl sounds interesting, but looks like a major change to some kernel moduls and the way the Linux developer expects how it works. I've found a paper from the author about it:

http://www.df.lth.se/~triad/pa.....ontrol.pdf

After thinking again about it, my favorite would be to compile it as a module and enable it by default at boot time in the standard Linux image distributions. This would work for most users, who expect I2C on the pins, but the users who want GPIO can use it by just unloading the module, without the need to modify the kernel.

I don't think passing config arguments at boot time is a good idea, because usually they are used to configure drivers, e.g. setting interrupts, not to disable or enable drivers, and with the module load/unload approach you could do it even at runtime, if some application needs to switch it.

So my suggestion is, that I'll test my driver if it works compiled in the kernel, and compiled as a module, and then I suggest with a patch to bcmrpi_cutdown_defconfig the use as a module.
User avatar
Posts: 92
Joined: Fri Jan 06, 2012 4:39 pm
by GadgetUK » Thu May 10, 2012 6:07 am
Frank,

Loadable kernel modules would be my preference too :)

Good news compiling against your linux source works, just need to get some external i2c devices to start testing.
Posts: 42
Joined: Thu Jan 19, 2012 6:02 pm
by GadgetUK » Thu May 10, 2012 9:41 am
Quick update to say I've got i2c working as a loadable module.

Frank you should have a github pull request for the change.
Posts: 42
Joined: Thu Jan 19, 2012 6:02 pm
by Frank Buss » Fri May 11, 2012 12:04 am
Thanks GadgetUK, I've merged it.

When I remove the I2C module with these commands:

rmmod i2c_gpio
rmmod i2c_algo_bit

I can use the pins as GPIO now.

And I've fine tuned a bit the udelay, now it is nearly 100 kHz, was about 76 kHz with the default settings and the default clock of 700 MHz:



The I2C settings are now in bcmrpi_cutdown_defconfig and bcmrpi_defconfig. In order to enable only the necessary new settings, I've found a nice tool to compare different kernel config files:

http://stoopidsimple.com/kccmp

The problem was, that in bcmrpi_cutdown_defconfig are much fewer entries, than in the .config after executing the oldconfig step. So I copied my modified .config file, created a clean .config with the oldconfig step from the bcmrpi_cutdown_defconfig file and then compared it. There were two I2C chip drivers which were not needed, the rest just CONFIG_I2C_* entries. I've added the necessary settings and created a new .config file, which works.

This should be a good stable base for new releases, until I've written the I2C driver for the hardware module on the microcontroller, I'll send a pull request.
User avatar
Posts: 92
Joined: Fri Jan 06, 2012 4:39 pm
by larsth » Fri May 11, 2012 6:51 am
Hi Frank Buss

Good work you had done :-)

... and I'm still in the RS Components queue.

I hope that will change today, or next friday - and the Pi will be in my postbox a week to 10 days later after it were purchased

I will begin my hardware development next weekend, and can help you with pair programming (also from the next weekend), if you need an extra set of eyes on some of the code for the BCM2835 I²C hardware.
Posts: 39
Joined: Sat Aug 27, 2011 9:51 pm
by dom » Fri May 11, 2012 11:21 am
@frank

make ARCH=arm savedefconfig

to produce a bcmrpi_cutdown_defconfig style config from .config (it removes all the default options)
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3991
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by Frank Buss » Fri May 11, 2012 11:26 am
Thanks, dom, this will save some time, I guess I should have RTFM :-)

Thanks for your offer, Lars, always good to have a code review.
User avatar
Posts: 92
Joined: Fri Jan 06, 2012 4:39 pm
by mabrowning » Tue May 15, 2012 2:11 am
What would it take to enable access to the HDMI I2C bus as well? Would there be a GPIO conflict?
Posts: 17
Joined: Mon May 14, 2012 4:14 pm
by mabrowning » Tue May 15, 2012 3:00 am
I see now that my question is nonsense. There are no GPIO regions defined for those connections. This I2C implementation only works because they share the same pins.

If we had a true hardware implementation which utilized the BSC features of the chipset, then it would be pretty trivial to enable access to the HDMI connected I2C bus, though the datasheet says not to.

(For a bit of context, I am looking to rewrite the EDID block on my monitor, since the RPi refuses to use the preferred mode it has in there now. At this point, I think I'll just write up a custom DVI cable that hooks directly to the GPIO pins instead.)
Posts: 17
Joined: Mon May 14, 2012 4:14 pm
by pygmy_giant » Tue May 15, 2012 10:41 am
Thank you again to those who have been working on this. My Pi is due due in 2 weeks and I am keen to start building a robot from the multitude of affordable I2C modules available. How can Joe Public get his hands on the kernel / driver and send instructions to the I2C bus from inside a language such as C++ / Python / Bash ? What are the banana skins to look out for?

Oh - just found this page: https://github.com/selsinork/raspberry- ... pi-drivers - will read on ... nope can't understand it ... can anyone post up a dummies guide to accessing I2C on the Pi from inside a language such as C++ / Python / Bash ?

Ah - just found this: http://www.frank-buss.de/io-expander/ Hmmm... need to read it a few times. Is an expander board still necessary or can I now use the adapted kernel to talk straight from the GPIO ( I thought the point of I2C was that it allowed IC to diredtly talk to each other) ?

Any clarification for simple folk would be appreciated - thanks in advance....
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by pygmy_giant » Tue May 15, 2012 10:35 pm
Sorry for exposing my ignorance and impatience - re-read the thread and figured out that the expander board Frank used was just for testing and that the kernel is available here: http://www.frank-buss.de/tmp/kernel.img

Not sure yet what to do with it or the config file posted here: http://pastebin.com/cHDdMjXv ?

Guessing I use them to replace the corresponding files in the debian image I have on my SD card ?

Think I can use the code examples on this page: http://www.frank-buss.de/io-expander/ to see how to access the driver.... am I right?
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by mabrowning » Wed May 16, 2012 2:19 am
pygmy_giant, Frank's gpio driver exports the two busses as standard i2c character device files. Any Linux utility or code than can read/write that will work fine(probably). I have used command line programs in the 'i2c-tools' debian package, but I'm not sure about binding in other languages.

Looking around, it appears that there is a python module in the i2c-tools repository, though it doesn't look like it comes in the debian package. There is also the libi2c-dev bindings, also related to the i2c-tools repo: http://www.lm-sensors.org/browser/i2c-tools/trunk
Posts: 17
Joined: Mon May 14, 2012 4:14 pm
by fulburncams » Wed May 16, 2012 7:39 am
Hi

Is there a step-by-step setup guide to setting up the i2c driver, I have seen references to loadable modules/new kernal images etc and would like to know 'what is what' in order to get going, I am new to linux but I am ok with hardware. I have already built my hardware and have led's blinking etc but do not understand how to get the i2c going.

Many thanks
Steve
User avatar
Posts: 70
Joined: Wed Nov 30, 2011 8:29 pm
by mabrowning » Wed May 16, 2012 7:55 am
fulburncams wrote:I would like to know 'what is what' in order to get going


So far, there is only 1 'what'. Frank Buss tweaked the kernel to use GPIO pins as I2C. Note that this doesn't actually use any special RPi hardware and could be done on any platform or pins that have GPIO.

He released a kernel image(http://www.frank-buss.de/tmp/kernel.img) and has a github(https://github.com/FrankBuss/linux/branches/rpi-patches) you can clone from to track his changes. I was able to swap his kernel with the kernel from the debian image, debian6-19-04-2012.zip, and everything worked. On bootup, there was /dev/i2c0-dev and /dev/i2c1-dev. Installing the 'i2c-tools' package allowed me to perform simple bus operations to test it.
Posts: 17
Joined: Mon May 14, 2012 4:14 pm
by fulburncams » Wed May 16, 2012 8:15 am
Thanks for the explanation. So I now have the .img file, is it as simple as replacing the current kernal.img in the /boot folder with the Frank Buss img file and rebooting.

Many thanks for your help.

Steve
User avatar
Posts: 70
Joined: Wed Nov 30, 2011 8:29 pm
by pygmy_giant » Wed May 16, 2012 12:26 pm
Aha - understand better now - expect more questions though - thanks in advance...
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by GadgetUK » Thu May 17, 2012 8:59 pm
I'd just like to say a thank you to Frank for his work on the i2c driver.
This has allowed me to use my RaspberryPi with OWFS to talk to i2c 1-wire bus masters.

Full details here http://go.je/iire
Posts: 42
Joined: Thu Jan 19, 2012 6:02 pm
by pygmy_giant » Fri May 18, 2012 1:13 am
Hi - GadgetUk - OWFS - elegant and intruiging - will research further...

I am embarrassed to admit I am a linux virgin - can you help me? I am guessing you are using either command line linux commands or bash script (is that the same thing) ? Are you using Arch Linux or Debian?

The reason I ask is that I would like to build a balancing robot using I2C modules such as a motor controller, gyro and accelerometer.

If I was to use the Pi for such a 'headless' robot project and need only input from the SD card on boot and output to the GPIO pins, could I go 'bare metal' with just the firmware, Frank's kernel, and a compiled binary called by Frank's kernel on the card....?

If so, what file name should I give my binary so that the kernel can find it and could I compile it with GCC?

I notice Frank's test code (http://www.frank-buss.de/io-expander/linux-i2c-test.c) has ' #include <linux/i2c-dev.h> ' in it but I don't know where he has got his i2c-dev.h file from - is it in the i2c-tools repository?
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by Frank Buss » Sat May 19, 2012 2:00 am
Good news, I've finished a first version of the driver for the BSC module, with interrupts. For faster turnaround cycles, I have written it as an external modul:
http://pastebin.com/hLCmdkb5
For rebuilding, you'll need a kernel cross compilation environment, as described at http://elinux.org/Rpi_kernel_compilation . Then you can install the modules on the host machine:
Code: Select all
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- modules_install

This makes the Makefile very easy:
Code: Select all
obj-m += i2c.o

all:
   make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -C /lib/modules/3.1.9+/build M=$(PWD) modules

clean:
   make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -C /lib/modules/3.1.9+/build M=$(PWD) clean

Now you can create the i2c.ko module with "make", copy it to the Raspberry Pi, and load it with "insmod i2c.ko", and unload it with "rmmod i2c.ko". Very useful for driver development, when the datasheet is not very clear. E.g. for the I2C driver it was not clear for me, if I can write to the FIFO before the transfer started (which is not possible), or the fact that the RXR bit was not set in the interrupt, but the RXD bit.

My Linux test program works with it, the device is /dev/i2c, for SDA0/SCL0. The next days I'll try to integrate it in my Linux kernel at https://github.com/FrankBuss/linux/ . The hardware part of the driver works, so this is just some Linux coding and should be finished until next weekend.

Some points to discuss:

  • how should we set the bus speed? For most devices 100 kHz should be ok, but I like the Omap concept, that you can specify it as a kernel parameter: i2c_rate=bus_id,clkrate . bus_id could be from 0 to 2 and clkrate from 100 to 400. Another idea would be a special IOCTL command in the driver to set it at runtime, but I didn't found a standard for it.
  • how do we set the alternative function of the GPIO pins? I've hardcoded it in the my first version, but I think it should be an exported function from the driver bcm2708_gpio.c
  • do we need the other functions as well from the i2c-dev interface? E.g. 10 bit addresses and SMBus commands: http://www.mjmwired.net/kernel/Document ... -interface (I've never seen 10 bit addresses in real life systems)
  • is the wait_event_interruptible_timeout concept clean, e.g. no race conditions, concept used as in other drivers?

When I integrate it in the Linux kernel, I'll clean up the resource handling, so that the GPIO pins are reserved from the kernel like with the current GPIO-I2C version, and the BSC IO areas will be defined as resources, too.
User avatar
Posts: 92
Joined: Fri Jan 06, 2012 4:39 pm
by Frank Buss » Sat May 19, 2012 2:14 am
Sorry, the "watch" flag was not ported to the new forum, so I didn't noticed the other articles in the thread.

fulburncams: currently it is all in development state, but if you like to build your own kernel, this is a nice step-by-step setup guide for it: http://elinux.org/RPi_Kernel_Compilation I guess it will be integrated in the main Raspberry Pi Linux kernel and then available in a later SD card image at some time

pygmy_giant: I think linux/i2c-dev.h was installed in my Debian image on the Raspberry Pi in /usr/include/linux/i2c-dev.h . If not, an "apt-get install --reinstall linux-kernel-headers" should install it (--reinstall is optional, if it was deleted). Then you can just compile it with "gcc linux-i2c-test.c".
User avatar
Posts: 92
Joined: Fri Jan 06, 2012 4:39 pm
by csoutreach » Sat May 19, 2012 8:45 am
Frank Buss wrote:[*] how do we set the alternative function of the GPIO pins? I've hardcoded it in the my first version, but I think it should be an exported function from the driver bcm2708_gpio.c


I tend to agree. I'm going to have a go with pinctrl and trying calling it with a function from my SPI driver. It should work the same for I2C. If that doesn't work then my plan was use functions in bcm2708_gpio

Part of me feels it should be setup in the board initialisation stuff, but then I accept Raspberry Pi is slightly different to standard embedded stuff and people might want to load and unload kernel modules and change these things at run time.
http://piface.openlx.org.uk/ Raspberry Pi IO Interface Board
User avatar
Posts: 32
Joined: Mon Nov 28, 2011 1:06 pm
by GadgetUK » Sat May 19, 2012 8:57 am
Frank, great work looking forward to trying this out, hopefully sometime today.
Posts: 42
Joined: Thu Jan 19, 2012 6:02 pm