I2C Detect Slave Method?
-
Good Day,
I am looking at using the i2c functionality of the Onion 2+ to be able to "detect" connect i2c slaves. unfortunately my tests with both python i2c library and c library both show that the omega returns "success" when reading and writing to an i2c slave that is not even there.
Does anyone know how to use i2c to detect if a slave is valid or not? i.e. If I try to "address" i2c slave "0x21" which is definitely not connected, how can I get some sort of error?
Thanks,
-
Hi,
Just some feedback if you happen to stumble across this topic in desperation. So my analysis is that there must be a bug with the Onion 2 I2C implementation. With that said @t-gabor had a thread that described how he managed to overcome some of the i2c limitations by moving to a "bit-banged" i2c approach.
For those interested the following method was used on a Omega Onion 2+ (firmware v0.1.10-b160):
- Install the relevant kernal modules (Thanks @t-gabor for compiling):
- kmod-i2c-gpio-custom_4.4.46-2_mipsel_24kc.ipk
- kmod-i2c-gpio_4.4.46-1_mipsel_24kc.ipk
- kmod-i2c-algo-bit_4.4.46-1_mipsel_24kc.ipk
This is done by downloading the above packages locally and running them in:
opkg install --force-depends kmod-i2c-algo-bit_4.4.46-1_mipsel_24kc.ipk
opkg install --force-depends kmod-i2c-gpio_4.4.46-1_mipsel_24kc.ipk
opkg install --force-depends kmod-i2c-gpio-custom_4.4.46-2_mipsel_24kc.ipkthe --force-depends is required as the onion thinks the kernel is at a too low version. if you are interested you can run:
root@Omega-XXXX:~# opkg list-installed | grep kernel kernel - 4.4.46-1-611bddde2031bc44b7d050f62495d772
In order to get the current kernel version, which you will find the last section of numbers are lower that the expected value for the compiled packages above.
Anyhow what confused me for a good few hours was that the opkg install will show errors at the end even though it was successful (i.e. notice the "Installing" and "Configuring" sections):
root@Omega-XXXX:~/ipk# opkg install --force-depends kmod-i2c-algo-bit_4.4.46-1_mipsel_24kc.ipk Installing kmod-i2c-algo-bit (4.4.46-1) to root... Configuring kmod-i2c-algo-bit. Collected errors: * satisfy_dependencies_for: Cannot satisfy the following dependencies for kmod-i2c-algo-bit: * kernel (= 4.4.46-1-d0a487fc7d1c9f083b7de0fb8c2a7c07) *
Once these modules are installed we need to load them using the following commands:
omega2-ctrl gpiomux set i2c gpio insmod i2c-algo-bit insmod i2c-gpio insmod i2c-gpio-custom bus0=1,5,4
with that you can now try the newly created /dev/i2c-1 device:
i2cdetect -y 1
And vola:
root@Omega-XXXX:~# i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
Anyhow to wrap things up you can do this setup automatically at bootup with the following init.d script. create using vi in /etc/init.d/I2Cbb
#!/bin/sh /etc/rc.common # Creates bit-banged i2c-device /dev/i2c-1 on pins 5,4. # NOTE: This hides /dev/i2c-0! START=98 STOP=97 start() { omega2-ctrl gpiomux set i2c gpio insmod i2c-algo-bit insmod i2c-gpio insmod i2c-gpio-custom bus0=1,5,4 } stop() { rmmod i2c-gpio-custom rmmod i2c-gpio rmmod i2c-algo-bit omega2-ctrl gpiomux set i2c i2c } restart() { stop start }
And another hour or so of frustration and rebooting reminded me again of missing the basics, do not forget to enable and make executable the script!
chmod 755 /etc/init.d/I2Cbb /etc/init.d/I2Cbb enable
*** EDIT ***
On an final note, using bitbanged I2C allows you to set the Onion I2C bus clock speed (SCL). To do this add the extra parameter to the the init.d scriptinsmod i2c-gpio-custom bus0=1,5,4,x
where x is is number based on the following formula:
I2C speed (kHz) = 500 / x
Cheers,
UFD
-
UFD, congratulations and thank you for sharing.
-
@UFD Thanks for this "solution" (or more workaround). This was the only way I was able to get my Python code towards a keller pressure meter work. So I'm lifting this fabioulus post
I'm still unable to fix my related problem with write a byte wait 8ms then read 5 bytes without specifying register.
http://community.onion.io/topic/2674/access-to-i2c-low-level-calls-through-python-onioni2cthere seems also to still be a open drain issue
https://community.onion.io/topic/2603/omega2-i2c-bus-is-not-open-drainWhy hasn't this been fixed in Omega2+? I have scanned several posts in the forum that probably has problems that are related to this. I2C is a vital bus doing smart IoT stuff for real. So if Onion would like to be part of commercial projects I2C needs to have top priority.
Could any of the staff comment?
-
In case any body else is looking for this.
If for example you wanted two I2C busses, you would do that like this.
Example: using GPIO 14 for the second SDA and GPIO 16 for the 2nd SCL
insmod i2c-gpio-custom bus0=1,5,4 bus1=2,14,16
and you can then verify them with
i2cdetect -y 1
and
i2cdetect -y 2
-
@UFD Please have a look at my pull request https://github.com/openwrt/openwrt/pull/831
It should fix all issues with I2C. It is using real I2C hardware of the chip (no bit-banging).
-
Hi,
Im glad you guys found this useful!
@Jeff-Seese Thanks for the additional information on spinning up multiple I2C channels (useful when you have fixed I2C address based devices).
@Jan-Breuer I will certainly look into this. It would be amazing if "real" I2C worked on the Omega.
Kind Regards,
UFD
-
@UFD said in I2C Detect Slave Method?:
Hello everyone!How I can use these kmod's with another version of kernel?
Now I have latest firmware and the kernel version is 4.4.74.
-
Is it possible to give links to newer compiled versions of (?):
kmod-i2c-gpio-custom_4.4.46-2_mipsel_24kc.ipk kmod-i2c-gpio_4.4.46-1_mipsel_24kc.ipk kmod-i2c-algo-bit_4.4.46-1_mipsel_24kc.ipk
There is no longer a b160 image at: http://repo.onion.io/omega2/images/ for some mysterious reason.
I have tried b159, but it gives me an "unable to open mmap file" error when I run "omega2-ctrl gpiomux set i2c gpio".
b175 gives me a "failed to find i2c-algo-bit" error when I run "insmod i2c-algo-bit"
-
@George-Gerber, it is there, you may miss it because it falls under 0.1.10 i.e. omega2p-v0.1.10-b160.bin
@Sergiy-Tarasov, I have had some success using what is most likely a hack and not recommended.
- Uncomment line 1 "reboot_core" in the file /etc/opkg/distfeeds.conf
- opkg update
- opkg --force-depends install kmod-i2c-gpio-custom
Now the hack, because it was for a higher kenel version the libraries are installed to /lib/module/<kenel-version> so we need to copy them across to the current version, in my case: - cp /lib/modules/4.4.131/* /lib/4.47/
Then proceed with the insmod as before.
Regards,
UFD
-
@UFD we fixed the driver for the hardware I2C controller. The main enhancements are:
- The
i2cdetect
command is now supported - clock stretching is supported
- support for unlimited message length
- support for repeated start sequences
Check out this blog post for more details
- The
-
@Lazar-Demin, Awesome news, thanks for letting me know. I will test very soon.
-
@Lazar-Demin Dear,
Thank you for your support, but Clock stretching is not clear; i.e how to change clock for i2c, in my case it is 100 kHz and I wan to chage it
what are the instructions for that,
thank you in all cases.
-
@Ammar-Assad the underlying driver supports clock stretching and will do so automatically, you don't have to specifically configure it.
As far as I remember, the Omega2 should support all I2C devices running from 100 kHz to 400 kHz out of the box.
-
@Lazar-Demin
Acutally I have upgraded my omega for that, it is still unclear for me how to controll clock speed, it is alway 100 kHz, the device is MPU9250
-
@Ammar-Assad Omega2(+)'s SCL clock frequency is 100kHz by default. According to its datasheet it's good for an MPU9250 slave.
Do you want a slower (eg. 10kHz) or a faster (eg. 400kHz) bus?
What is your real problem?@Ammar-Assad wrote
it is still unclear for me how to controll clock speed, it is alway 100 kHz
Clock stretching is not clear; i.e how to change clock for i2c, in my case it is 100 kHz and I wan to chage it
As you know the original I2C communication speed (I2C Standard mode) was defined with a maximum of 100 kbit per second and the SCL clock is always determined / generated by the I2C master.
The clock stretching is a completely different thing.
-
@György-Farkas Thanks for your concern, Actually I want to faster it if it is possible.
-
@Ammar-Assad
MediaTek MT7688 Datasheet
5.10 I2C Controller
Module name: I2C Base address: (+10000900h)
Address 10000940 SM0CFG1 SERIAL INTERFACE MASTER 0 CONFIG 1 REGISTER
bit 27:16 SM0_CLK_DIV SIF master 0 clock divide value
This is used to set the divider to generate expected SCL.- Omega2(+) default 100kHz
40MHz / 400 = 100kHz
400 = 0x190
0x8190
800F
devmem 0x10000940 0x8190800F
- set to 400kHz
40MHz / 100 = 400kHz
100 = 0x64
0x8064
800F
devmem 0x10000940 32 0x8064800F devmem 0x10000940 0x8064800F
Good luck!
- Omega2(+) default 100kHz
-
-
@Ammar-Assad Here you are a quick 'proof-of-concept' with a "full" BusyBox.
# Omega2+ root@Omega-99A5:/# oupgrade -v > Device Firmware Version: 0.2.2 b200 root@Omega-99A5:/# cd ~ root@Omega-99A5:~# wget https://www.busybox.net/downloads/binaries/1.28.1-defconfig-multiarch/busybox-mipsel root@Omega-99A5:~# chmod +x busybox-mipsel root@Omega-99A5:~# ./busybox-mipsel BusyBox v1.28.1 (2018-02-15 14:34:02 CET) multi-call binary. BusyBox is copyrighted by many authors between 1998-2015. Licensed under GPLv2. See source distribution for detailed copyright notices. Usage: busybox [function [arguments]...] or: busybox --list[-full] or: busybox --install [-s] [DIR] or: function [arguments]... BusyBox is a multi-call binary that combines many common Unix utilities into a single executable. Most people will create a link to busybox for each function they wish to use and BusyBox will act like whatever it was invoked as. Currently defined functions: [, [[, acpid, add-shell, addgroup, adduser, adjtimex, arch, arp, arping, ash, awk, base64, basename, beep, blkdiscard, blkid, blockdev, bootchartd, brctl, bunzip2, bzcat, bzip2, cal, cat, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, conspy, cp, cpio, crond, crontab, cryptpw, cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname, dos2unix, dpkg, dpkg-deb, du, dumpkmap, dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, ether-wake, expand, expr, factor, fakeidentd, fallocate, false, fatattr, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, flock, fold, free, freeramdisk, fsck, fsck.minix, fsfreeze, fstrim, fsync, ftpd, ftpget, ftpput, fuser, getopt, getty, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hexedit, hostid, hostname, httpd, hush, hwclock, i2cdetect, i2cdump, i2cget, i2cset, id, ifconfig, ifdown, ifenslave, ifplugd, ifup, inetd, init, insmod, install, ionice, iostat, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, ipneigh, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, link, linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login, logname, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsscsi, lsusb, lzcat, lzma, lzop, makedevs, makemime, man, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.minix, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint, mpstat, mt, mv, nameif, nanddump, nandwrite, nbd-client, nc, netstat, nice, nl, nmeter, nohup, nproc, nsenter, nslookup, ntpd, nuke, od, openvt, partprobe, passwd, paste, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, pmap, popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev, readahead, readlink, readprofile, realpath, reboot, reformime, remove-shell, renice, reset, resize, resume, rev, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run-init, run-parts, runlevel, runsv, runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setarch, setconsole, setfattr, setfont, setkeycodes, setlogcons, setpriv, setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha3sum, sha512sum, showkey, shred, shuf, slattach, sleep, smemcap, softlimit, sort, split, ssl_client, start-stop-daemon, stat, strings, stty, su, sulogin, sum, sv, svc, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, taskset, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, truncate, tty, ttysize, tunctl, ubiattach, ubidetach, ubimkvol, ubirename, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd, udpsvd, uevent, umount, uname, unexpand, uniq, unix2dos, unlink, unlzma, unshare, unxz, unzip, uptime, users, usleep, uudecode, uuencode, vconfig, vi, vlock, volname, w, wall, watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xxd, xz, xzcat, yes, zcat, zcip root@Omega-99A5:~# ./busybox-mipsel devmem 0x10000940 0x818F800F root@Omega-99A5:~# ./busybox-mipsel devmem 0x10000940 32 0x8064800F root@Omega-99A5:~# ./busybox-mipsel devmem 0x10000940 0x8064800F
FW 0.2.2 b200 - presently the divider is '0x18F = 399' instead of '0x190 = 400'.
Please ask one of Onion administrators ( @Zheng-Han @Lazar-Demin @Pavel-Metrokhin) why