Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: How to I2C in RPi3B+ (also gpioiic) ?



"Dr. Nicola Mingotti" <nmingotti%gmail.com@localhost> writes:

> Hi,

Hello....

> I am trying to get I2C to work in RPi3B+ (possibly later in BBB) in 
> NetBSD 10.0 Release.
>
> I am doing experiments, but it does not seem to work or i did not 
> understand
> how to make it.
>
> To get started I am connecting an external clock DS3231, a device I used 
> in the past.
>

[snip]

> Now i try to replicate the same in NetBSD 10.0 in 2 ways
>
> ===============================================================
> === NetBSD 10.0, method 1, using builtin i2c (via DTS, i guess)
> ===============================================================
>
>
> . wiring is now the same as in Linux
>
> . check if i2c is there in dmesg
> $> doas dmesg | grep -i iic
> [     1.000004] bsciic0 at simplebus1: Broadcom Serial Controller
> [     1.000004] bsciic0: interrupting on icu irq 53
> [     1.000004] iic0 at bsciic0: I2C bus
> [     1.000004] bsciic1 at simplebus1: Broadcom Serial Controller
> [     1.000004] bsciic1: interrupting on icu irq 53
> .... the same for iic1, iic2
>
> . try to see if i can see my device at address 0x68
>
> $> doas i2cscan /dev/iic0
> ....
> /dev/iic0: found device at 0x74
> /dev/iic0: found device at 0x75
> /dev/iic0: found device at 0x76
> /dev/iic0: found device at 0x77
> /dev/iic0: 103 devices found
>
> => failed, it found devices everywhere
> => same result using parameter "-r"
> => same result on /dev/iic1 and /dev/iic2

i2cscan has a problem in 10.x and -current on the RPI and will return
bogus results.  In 9.x, i2cscan worked fine.  There is a PR out there
about this with a proposed fix that may or may not be correct.

>
> ================================================
> === NetBSD 10.0, method 2, i try to use gpioiic
> =================================================
>
> This method is more general, does not depend on board hardware
> and if it worked it would work also in BeagleBone, so it is actually
> my first choice, for ease of portability.
>

[snip]

gpioiic has the same problems with i2cscan as the built in iic
controller.  It returns bogus results in 10.x and -current.

> =======================================
>
>
> Questions.
>
> 1. Is anybody able to get some form of I2C to work ?

I use I2C on RPI device all of the time and it works fine.

> 2. Does it exist a command similar to i2cget in NetBSD to query
>     directly a device via shell ? Otherwise, is there a code
>     snipped around I can start from to get the same thing in C ?

That was sort of what i2cscan is all about, but as mentioned, it doesn't
work correctly and even if it did, it would only tell you something was
there.  The /dev/iicX devices do support a number of ioctl calls that
would allow you to perform I2C operations against I2C devices from
userland, but there is no ready made program to help you do that.

> 3. using gpioiic the widget was recognized and it seems
>     the device dsrtc0 was created (I guess a driver was found) but
> .. Where is it ? I don't see it in /dev/
> .. How do I use that device dsrtc0 ?
>

If you wanted to see results, you may have picked a hard I2C device to
use.  The DS1307 doesn't have a device in /dev..  it is only updated by
the system as a RTC dodad.  You may want to try one of the I2C
environmental sensors instead where the results will show up in envstat
output and in some cases have /dev/ devices.

As a brief aside, and not to confuse the main point, there is support in
the DSxxxx driver for the possibility of using any NVRAM that may exist
on the DSxxxx chip.  The DS1307 has such NVRAM but there is a missing
line in the conf file and a major/minor device is never set up for it.
If you add that and build a kernel and then create the proper device in
/dev/ you can access the NVRAM on the DSxxxx chip.  It does work.


[snip]


Back to the DS1307....

To use that I2C device you have to have a device tree overlay that says
that the device is there.  Not all I2C devices will require that, but
the DS1307 will.  I don't have a DS1307 connected to my RPI3, but I do
have a DS3231 connected to a RPI3 and that is simular.  I compile the
following with the dtc command and place it in /boot/overlays and name
the result ds3231_rpi3.dtbo.  I then edit /boot/config.txt and put
dtoverlay=ds3231_rpi3.dtbo in there and reboot (you would use something
like dallas,ds1307 for the compatibilty line):

/dts-v1/;

/ {
        compatible = "brcm,bcm2837";

        fragment@0 {
                target-path = "/soc/i2c@7e804000";

                __overlay__ {
                        status = "okay";
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;
                        clock-frequency = <0x61a80>;

                        dsrtc@68 {
                                compatible = "dallas,ds3231";
                                reg = <0x68>;
                        };
                };
        };
};

(there are probably better overlays then the one I use)

If the kernel you are using already has the needed device driver, then
on reboot the device should show up in dmesg and ofctl.  If the driver
is not present in your kernel, then there are a couple of paths to
follow:

1) If the device driver has been modularized, then you may be able to
load the device driver module.  This will require that you identify what
the driver is called (see the contents of /stand/*), put the needed
entries in /etc/modules.conf and enable modules in /etc/rc.conf.  ...
however, the DSxxxx driver hasn't been modularized at this point as far
as I can tell.

2) Compile a custom kernel and boot it.  You have to use this method if
there isn't a module and the kernel you are using doesn't have the
driver.  I use the following for my RPI devices that have DS1307 or
DS3231 RTC clocks:

include "arch/evbarm/conf/GENERIC"

no dsrtc* at iic?
dsrtc* at iic2 addr 0x68 flags 1307
dsrtc* at iic2 addr 0x68 flags 3231

no ac100ic*     at iic?                 # AC100 integrated audio codec and RTC
no as3722pmic*  at iic?
no as3722reg*   at as3722pmic?
no axp20x*      at iic?                 # AXP209 Power Management IC
no axp20xreg*   at axp20x?
no axp22x*      at iic?                 # AXP221 Power Management IC
no axppmic*     at iic?                 # X-Powers AXP Power Management IC
no axpreg*      at axppmic?
no max77620pmic*        at iic?
no pcf8563rtc*  at iic?                 # PCF8563 RTC
no seeprom*     at iic?                 # AT24Cxx Serial EEPROM
no sy8106a*     at iic?                 # Silergy SY81061 regulator
no tcakp*               at iic?                 # TI TCA8418 Keypad Scan IC
no tcagpio*     at iic?
no tdahdmi*     at iic?                 # NXP TDA19988 HDMI encoder
no titemp*      at iic?
no tps65217pmic*        at iic?                 # TI TPS65217 Power Management IC
no tps65217reg* at tps65217pmic?
no twl*         at iic?                 # TI TWL4030 Power Management IC
no lmtemp*      at iic?

In my case, I wanted to be very specific on how the RTC device was
included.  Its on I2C bus iic2 at address 0x68 (no other bus and no
other address).  The other 'no ...'  lines are to eliminate phantom
devices that can result from using the GENERIC kernel on a RPI.

You would compile this in the usual and customary manor that one
compiles NetBSD kernels and put in in /boot.  Edit /boot/config.txt and
change the kernel entry if you called your kernel something unique.

> bye
>
> Nicola Mingotti

I glossed over a lot of details... but in the end, I2C does function ..
it just doesn't really work at all like it does in Linux.



-- 
Brad Spencer - brad%anduin.eldar.org@localhost - KC8VKS - http://anduin.eldar.org


Home | Main Index | Thread Index | Old Index