Difference between revisions of "EBC Exercise 12 I2C"
m (Added Header/Footer) |
m (→via a kernel driver: Added finding instructions) |
||
(36 intermediate revisions by 7 users not shown) | |||
Line 2: | Line 2: | ||
[[Category:EmbeddedBeagleClass]] | [[Category:EmbeddedBeagleClass]] | ||
{{YoderHead}} | {{YoderHead}} | ||
+ | {{EBC3.8}}This page is for the 3.8 kernel. See [[EBC Exercise 12 I2C - xM]] for the 3.2 kernel. | ||
− | [http://en.wikipedia.org/wiki/I%C2%B2C I²C] is a "two-wire interface" standard that is used to attach low-speed peripherals to an embedded system. In this exercise we will wire up a couple of I²C temperature sensors ([http://www. | + | [http://en.wikipedia.org/wiki/I%C2%B2C I²C] is a "two-wire interface" standard that is used to attach low-speed peripherals to an embedded system. In this exercise we will wire up a couple of I²C temperature sensors ([http://www.ti.com/product/tmp101 TC74]) and learn how to read their values. |
== The Hardware == | == The Hardware == | ||
+ | === bone === | ||
+ | The AM3359 on the BeagleBone has three I²C controllers (Section 21 of the [http://www.ti.com/product/am3359 TRM]). You can see which ones are configured at boot time by running the following on the Beagle: | ||
− | + | bone$ '''dmesg -H | grep i2c''' | |
+ | [ +0.001817] omap_i2c 44e0b000.i2c: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/pinmux_i2c0_pins, deferring probe | ||
+ | [ +0.001349] omap_i2c 4802a000.i2c: bus 1 rev0.11 at 100 kHz | ||
+ | [ +0.002590] omap_i2c 4819c000.i2c: bus 2 rev0.11 at 100 kHz | ||
+ | [ +0.002904] i2c /dev entries driver | ||
+ | [ +0.000219] omap_i2c 44e0b000.i2c: bus 0 rev0.11 at 400 kHz | ||
+ | [Sep 5 14:56] omap_i2c 4802a000.i2c: timeout waiting for bus ready | ||
+ | [ +1.008030] omap_i2c 4802a000.i2c: timeout waiting for bus ready | ||
+ | [ +1.008041] omap_i2c 4802a000.i2c: timeout waiting for bus ready | ||
− | + | Here we see three buses, one running at 400 kHz and the other two at 100 kHz. Table 11 from the SRM shows buses 1 and 2 are brought out to the P9 Expansion Header. | |
− | + | We'll use 2. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | The following commands require you to be in the *i2c* group. To check if you are a member of the i2c group, run the command | |
+ | bone$ '''groups''' | ||
− | + | If the *i2c* group is not listed, add yourself to the group with | |
− | + | bone$ '''sudo usermod -g i2c debian''' | |
− | + | ||
+ | You can see what's on the i2c buses with | ||
+ | bone$ '''i2cdetect -y -r 0''' | ||
+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f | ||
+ | 00: -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 20: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 30: -- -- -- -- 34 -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 70: -- -- -- -- -- -- -- -- | ||
+ | |||
+ | bone$ '''i2cdetect -y -r 1''' | ||
+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f | ||
+ | 00: -- -- ^C | ||
+ | Hmmm... bus 1 is reading slowly. That means something isn't hooked up right on it. | ||
+ | |||
+ | bone$ '''i2cdetect -y -r 2''' | ||
+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f | ||
+ | 00: -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 40: -- -- -- -- -- -- -- -- 48 -- 4a -- -- -- -- -- | ||
+ | 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 70: -- -- -- -- -- -- -- -- | ||
+ | |||
+ | I have something at addresses 0x48 and 0x4a on bus 2. | ||
+ | |||
+ | [[File:HeaderP9.jpg|.jpg|800px]] | ||
− | + | These signals are 3.3V and the TMP101 runs on 2.7 to 5.5V so we are in luck. | |
− | + | I²C is a two-wire bus. The two wires are | |
+ | # Serial Clock (SCL), is an input to the TMP101 and is used to clock data into and out of the TMP101. | ||
+ | # Serial Data (SDA), is bidirectional and carries the data to and from the TMP101. | ||
− | + | The only other two pins on the TMP101 that you need to use are the Power Supply (Vdd) and Ground, unless you want to use OS/ALERT, in which case you need to add a pull up resistor to Vdd, and then run another wire to a GPIO in order to properly trigger an interrupt. | |
− | + | [[File:Bone gpio.JPG|300px]] | |
+ | [[File:BoneGPIO.png|300px]] | ||
− | + | Wire up the TMP101 to the Beagle by attaching the Vdd to the 3.3V '''+''' bus, the GND to the '''-''' bus and SDA to SDA (pin 20) and SCL to SCL (pin 19). '''You will also need to attach two pull-up resistors'''. Get two 4.7KΩ resistors. Attach one between SDA and Vdd. Attach the other between SCL and Vdd. | |
− | + | Your TMP101 should be labeled with '''T101'''. If you have another TMP101 you can wire it in parallel with the first be sure to wire the '''ADD0''' pin differently. That is, attach SDA to SDA and SCL to SCL, etc. No need for additional pull up resistors. | |
− | |||
− | |||
+ | == The Software == | ||
=== From the Shell === | === From the Shell === | ||
− | The Beagle brings out I²C bus | + | The Beagle brings out I²C bus 1 to the Expansion Header. You can see what devices are on the bus by using the [http://www.lm-sensors.org/wiki/man/i2cdetect i2cdetect] command. On your Beagle try: |
− | + | bone$ '''i2cdetect -y -r 2''' | |
0 1 2 3 4 5 6 7 8 9 a b c d e f | 0 1 2 3 4 5 6 7 8 9 a b c d e f | ||
00: -- -- -- -- -- -- -- -- -- -- -- -- -- | 00: -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
− | 10: -- -- -- -- -- -- -- -- -- -- -- | + | 10: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- |
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
− | 30: -- -- -- -- -- -- -- -- -- -- -- -- | + | 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
− | 40: -- -- -- -- -- -- -- -- 48 | + | 40: -- -- -- -- -- -- -- -- 48 48 4a -- -- -- -- -- |
− | 50: | + | 50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- |
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
− | 70: -- -- -- -- -- -- -- -- | + | 70: -- -- -- -- -- -- -- -- |
− | What you see is a list of all the devices found on the bus. I've attached | + | What you see is a list of all the devices found on the bus. I've attached three TMP101's, and wired their '''ADD0''' line differently. Their address are <code>1001 000</code>, <code>1001 010</code> and <code>1001 010</code> respectively. Converting to hex you get <code>0x48</code>, <code>0x49</code> and <code>0x4a</code>. You can see the three appear in the ic2detect. |
− | Each | + | Each TMP101 has four registers. Check the TMP101 manual for details. We're interested in the TEMP register. You can read it with: |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | bone$ '''i2cget -y 2 0x48 0''' | |
− | + | 0x1b | |
− | |||
− | 0x1b | ||
The '''-y''' says don't ask me, just do it. '''2''' says use bus 2. '''0x48''' is the device address and '''0''' is the register number. The value returned is the temperature in degrees C. | The '''-y''' says don't ask me, just do it. '''2''' says use bus 2. '''0x48''' is the device address and '''0''' is the register number. The value returned is the temperature in degrees C. | ||
Line 78: | Line 103: | ||
# Write a script to run ic2get in a loop and watch the temperature. Hold the device between your fingers. Does the temp go up? | # Write a script to run ic2get in a loop and watch the temperature. Hold the device between your fingers. Does the temp go up? | ||
− | === | + | === via a kernel driver === |
+ | The cleanest way to read the temperature from at TMP101 sensor is to use the kernel drive. | ||
+ | |||
+ | Assuming the TMP101 is on bus 2 (the last digit is the bus number) | ||
+ | |||
+ | bone$ '''cd /sys/class/i2c-adapter/i2c-2''' | ||
+ | bone$ '''ls -ls''' | ||
+ | total 0 | ||
+ | drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0054 | ||
+ | drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0055 | ||
+ | drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0056 | ||
+ | drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0057 | ||
+ | --w--w---- 1 root gpio 4096 Aug 13 11:58 delete_device | ||
+ | lrwxrwxrwx 1 root gpio 0 Aug 13 11:59 device -> ../../4819c000.i2c | ||
+ | drwxrwxr-x 3 root gpio 0 Aug 13 11:58 i2c-dev | ||
+ | -r--r--r-- 1 root gpio 4096 Aug 13 11:58 name | ||
+ | --w--w---- 1 root gpio 4096 Aug 13 11:58 new_device | ||
+ | lrwxrwxrwx 1 root gpio 0 Aug 13 11:59 of_node -> ../../../../../firmware/devicetree/base/ocp/i2c@4819c000 | ||
+ | drwxrwxr-x 2 root gpio 0 Aug 13 11:58 power | ||
+ | lrwxrwxrwx 1 root gpio 0 Aug 13 11:59 subsystem -> ../../../../../bus/i2c | ||
+ | -rw-rw-r-- 1 root gpio 4096 Aug 13 11:58 uevent | ||
− | Another approach to using I²C on the Beagle is from a C program. You can open <code>/dev/i2c- | + | Assuming the TMP101 is at address 0x48 |
+ | bone$ '''echo tmp101 0x48 > new_device''' | ||
+ | This tells the kernel you have a TMP101 sensor at address 0x48. Check the log to be sure. | ||
+ | bone$ '''dmesg -H | tail -3''' | ||
+ | [Sep20 13:21] systemd: 38 output lines suppressed due to ratelimiting | ||
+ | [Sep20 15:42] i2c i2c-2: new_device: Instantiated device tmp101 at 0x48 | ||
+ | [ +0.049729] lm75 2-0048: hwmon0: sensor 'tmp101' | ||
+ | |||
+ | Yes, it's there, now see what happened. | ||
+ | bone$ '''ls''' | ||
+ | '''2-0048''' 2-0055 2-0057 device name of_node subsystem | ||
+ | 2-0054 2-0056 delete_device i2c-dev new_device power uevent | ||
+ | Notice a new directory has appeared. It's for i2c bus 2, address 0x48. Look into it. | ||
+ | |||
+ | bone$ '''cd 2-0048/hwmon/hwmon0''' | ||
+ | bone$ '''ls -F''' | ||
+ | device@ name power/ subsystem@ temp1_input temp1_max temp1_max_hyst uevent update_interval | ||
+ | bone$ '''cat temp1_input''' | ||
+ | 24250 | ||
+ | There is the temperature in milli-degrees C. | ||
+ | |||
+ | ==== Finding which devices work ==== | ||
+ | You can try the Linux Kernel Driver Database, https://cateee.net/lkddb/ | ||
+ | |||
+ | Or, go to | ||
+ | |||
+ | bone$ '''cd /lib/modules/4.19.94-ti-r64/kernel/drivers/iio''' | ||
+ | bone$ '''find . -iname "*vl*" | ||
+ | ./proximity/vl53l0x-i2c.ko.xz | ||
+ | ./light/vl6180.ko.xz | ||
+ | bone$ '''modinfo vl6180''' | ||
+ | filename: /lib/modules/4.19.94-ti-r64/kernel/drivers/iio/light/vl6180.ko.xz | ||
+ | license: GPL | ||
+ | description: STMicro VL6180 ALS, range and proximity sensor driver | ||
+ | author: Manivannan Sadhasivam <manivannanece23@gmail.com> | ||
+ | author: Peter Meerwald-Stadler <pmeerw@pmeerw.net> | ||
+ | alias: of:N*T*Cst,vl6180C* | ||
+ | alias: of:N*T*Cst,vl6180 | ||
+ | alias: i2c:vl6180 | ||
+ | depends: | ||
+ | intree: Y | ||
+ | name: vl6180 | ||
+ | vermagic: 4.19.94-ti-r64 SMP preempt mod_unload modversions ARMv7 p2v8 | ||
+ | |||
+ | === From C (skip) === | ||
+ | |||
+ | Another approach to using I²C on the Beagle is from a C program. You can open <code>/dev/i2c-1</code> and do <code>ioctl</code> calls on it to read and write data. | ||
Pull the exercises | Pull the exercises | ||
− | + | bone$ '''cd exercises''' | |
− | + | bone$ '''git pull''' | |
− | + | bone$ '''cd i2c''' | |
Compile and run '''myi2cget.c'''. | Compile and run '''myi2cget.c'''. | ||
− | + | bone$ '''make''' | |
− | + | bone$ '''./myi2cget''' | |
Usage: ./myi2cget <i2c-bus> <i2c-address> <register> | Usage: ./myi2cget <i2c-bus> <i2c-address> <register> | ||
− | + | bone$ '''./myi2cget 2 72 0''' | |
0x1b (27) | 0x1b (27) | ||
− | It takes many of the arguments as '''i2cget''', but none of the flags. | + | It takes many of the arguments as '''i2cget''', but none of the flags. It's very stripped down version of i2cget. Note that 72 is the decimal representation of 0x48. myi2cget requires the use of decimal numbers, while the "traiditional" i2cget can use either decimal or hex representations. |
− | |||
− | |||
− | |||
− | |||
− | + | The original '''i2cget''' code came from [http://www.lm-sensors.org/wiki/man/i2cget here]. | |
− | |||
− | |||
− | |||
− | |||
− | |||
== References == | == References == | ||
− | # [http://www. | + | # [http://www.byteparadigm.com/applications/introduction-to-i2c-and-spi-protocols/ Introduction to i2c and SPI] |
+ | # [http://www.ti.com/product/tmp101 TMP101] I2C Temperature Sensor information. | ||
# I got a lot information from [[Interfacing with I2C Devices]]. | # I got a lot information from [[Interfacing with I2C Devices]]. | ||
# [http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=69&Itemid=78 This] appears to have some nice I2C information for the Gumstix. It should also work for the Beagle. | # [http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=69&Itemid=78 This] appears to have some nice I2C information for the Gumstix. It should also work for the Beagle. |
Revision as of 11:50, 5 November 2021
Embedded Linux Class by Mark A. Yoder
This page is for the 3.8 kernel. See EBC Exercise 12 I2C - xM for the 3.2 kernel.
I²C is a "two-wire interface" standard that is used to attach low-speed peripherals to an embedded system. In this exercise we will wire up a couple of I²C temperature sensors (TC74) and learn how to read their values.
Contents
The Hardware
bone
The AM3359 on the BeagleBone has three I²C controllers (Section 21 of the TRM). You can see which ones are configured at boot time by running the following on the Beagle:
bone$ dmesg -H | grep i2c [ +0.001817] omap_i2c 44e0b000.i2c: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/pinmux_i2c0_pins, deferring probe [ +0.001349] omap_i2c 4802a000.i2c: bus 1 rev0.11 at 100 kHz [ +0.002590] omap_i2c 4819c000.i2c: bus 2 rev0.11 at 100 kHz [ +0.002904] i2c /dev entries driver [ +0.000219] omap_i2c 44e0b000.i2c: bus 0 rev0.11 at 400 kHz [Sep 5 14:56] omap_i2c 4802a000.i2c: timeout waiting for bus ready [ +1.008030] omap_i2c 4802a000.i2c: timeout waiting for bus ready [ +1.008041] omap_i2c 4802a000.i2c: timeout waiting for bus ready
Here we see three buses, one running at 400 kHz and the other two at 100 kHz. Table 11 from the SRM shows buses 1 and 2 are brought out to the P9 Expansion Header. We'll use 2.
The following commands require you to be in the *i2c* group. To check if you are a member of the i2c group, run the command
bone$ groups
If the *i2c* group is not listed, add yourself to the group with
bone$ sudo usermod -g i2c debian
You can see what's on the i2c buses with
bone$ i2cdetect -y -r 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- 34 -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
bone$ i2cdetect -y -r 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- ^C
Hmmm... bus 1 is reading slowly. That means something isn't hooked up right on it.
bone$ i2cdetect -y -r 2 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- 48 -- 4a -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
I have something at addresses 0x48 and 0x4a on bus 2.
These signals are 3.3V and the TMP101 runs on 2.7 to 5.5V so we are in luck.
I²C is a two-wire bus. The two wires are
- Serial Clock (SCL), is an input to the TMP101 and is used to clock data into and out of the TMP101.
- Serial Data (SDA), is bidirectional and carries the data to and from the TMP101.
The only other two pins on the TMP101 that you need to use are the Power Supply (Vdd) and Ground, unless you want to use OS/ALERT, in which case you need to add a pull up resistor to Vdd, and then run another wire to a GPIO in order to properly trigger an interrupt.
Wire up the TMP101 to the Beagle by attaching the Vdd to the 3.3V + bus, the GND to the - bus and SDA to SDA (pin 20) and SCL to SCL (pin 19). You will also need to attach two pull-up resistors. Get two 4.7KΩ resistors. Attach one between SDA and Vdd. Attach the other between SCL and Vdd.
Your TMP101 should be labeled with T101. If you have another TMP101 you can wire it in parallel with the first be sure to wire the ADD0 pin differently. That is, attach SDA to SDA and SCL to SCL, etc. No need for additional pull up resistors.
The Software
From the Shell
The Beagle brings out I²C bus 1 to the Expansion Header. You can see what devices are on the bus by using the i2cdetect command. On your Beagle try:
bone$ i2cdetect -y -r 2 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- 48 48 4a -- -- -- -- -- 50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
What you see is a list of all the devices found on the bus. I've attached three TMP101's, and wired their ADD0 line differently. Their address are 1001 000
, 1001 010
and 1001 010
respectively. Converting to hex you get 0x48
, 0x49
and 0x4a
. You can see the three appear in the ic2detect.
Each TMP101 has four registers. Check the TMP101 manual for details. We're interested in the TEMP register. You can read it with:
bone$ i2cget -y 2 0x48 0 0x1b
The -y says don't ask me, just do it. 2 says use bus 2. 0x48 is the device address and 0 is the register number. The value returned is the temperature in degrees C.
- Convert the hex temperature to decimal. Is the value reasonable?
- Write a script to run ic2get in a loop and watch the temperature. Hold the device between your fingers. Does the temp go up?
via a kernel driver
The cleanest way to read the temperature from at TMP101 sensor is to use the kernel drive.
Assuming the TMP101 is on bus 2 (the last digit is the bus number)
bone$ cd /sys/class/i2c-adapter/i2c-2 bone$ ls -ls total 0 drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0054 drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0055 drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0056 drwxrwxr-x 3 root gpio 0 Aug 13 11:58 2-0057 --w--w---- 1 root gpio 4096 Aug 13 11:58 delete_device lrwxrwxrwx 1 root gpio 0 Aug 13 11:59 device -> ../../4819c000.i2c drwxrwxr-x 3 root gpio 0 Aug 13 11:58 i2c-dev -r--r--r-- 1 root gpio 4096 Aug 13 11:58 name --w--w---- 1 root gpio 4096 Aug 13 11:58 new_device lrwxrwxrwx 1 root gpio 0 Aug 13 11:59 of_node -> ../../../../../firmware/devicetree/base/ocp/i2c@4819c000 drwxrwxr-x 2 root gpio 0 Aug 13 11:58 power lrwxrwxrwx 1 root gpio 0 Aug 13 11:59 subsystem -> ../../../../../bus/i2c -rw-rw-r-- 1 root gpio 4096 Aug 13 11:58 uevent
Assuming the TMP101 is at address 0x48
bone$ echo tmp101 0x48 > new_device
This tells the kernel you have a TMP101 sensor at address 0x48. Check the log to be sure.
bone$ dmesg -H | tail -3 [Sep20 13:21] systemd: 38 output lines suppressed due to ratelimiting [Sep20 15:42] i2c i2c-2: new_device: Instantiated device tmp101 at 0x48 [ +0.049729] lm75 2-0048: hwmon0: sensor 'tmp101'
Yes, it's there, now see what happened.
bone$ ls 2-0048 2-0055 2-0057 device name of_node subsystem 2-0054 2-0056 delete_device i2c-dev new_device power uevent
Notice a new directory has appeared. It's for i2c bus 2, address 0x48. Look into it.
bone$ cd 2-0048/hwmon/hwmon0 bone$ ls -F device@ name power/ subsystem@ temp1_input temp1_max temp1_max_hyst uevent update_interval bone$ cat temp1_input 24250
There is the temperature in milli-degrees C.
Finding which devices work
You can try the Linux Kernel Driver Database, https://cateee.net/lkddb/
Or, go to
bone$ cd /lib/modules/4.19.94-ti-r64/kernel/drivers/iio bone$ find . -iname "*vl*" ./proximity/vl53l0x-i2c.ko.xz ./light/vl6180.ko.xz bone$ modinfo vl6180 filename: /lib/modules/4.19.94-ti-r64/kernel/drivers/iio/light/vl6180.ko.xz license: GPL description: STMicro VL6180 ALS, range and proximity sensor driver author: Manivannan Sadhasivam <manivannanece23@gmail.com> author: Peter Meerwald-Stadler <pmeerw@pmeerw.net> alias: of:N*T*Cst,vl6180C* alias: of:N*T*Cst,vl6180 alias: i2c:vl6180 depends: intree: Y name: vl6180 vermagic: 4.19.94-ti-r64 SMP preempt mod_unload modversions ARMv7 p2v8
From C (skip)
Another approach to using I²C on the Beagle is from a C program. You can open /dev/i2c-1
and do ioctl
calls on it to read and write data.
Pull the exercises
bone$ cd exercises bone$ git pull bone$ cd i2c
Compile and run myi2cget.c.
bone$ make bone$ ./myi2cget Usage: ./myi2cget <i2c-bus> <i2c-address> <register> bone$ ./myi2cget 2 72 0
0x1b (27)
It takes many of the arguments as i2cget, but none of the flags. It's very stripped down version of i2cget. Note that 72 is the decimal representation of 0x48. myi2cget requires the use of decimal numbers, while the "traiditional" i2cget can use either decimal or hex representations.
The original i2cget code came from here.
References
- Introduction to i2c and SPI
- TMP101 I2C Temperature Sensor information.
- I got a lot information from Interfacing with I2C Devices.
- This appears to have some nice I2C information for the Gumstix. It should also work for the Beagle.
- i2c via Python
Embedded Linux Class by Mark A. Yoder