I had never tried I2C in the Arduino environment on Edison (only in node.js/linux) so I thought I would give it a try. I tested an I2C 16x2 Character display and everything worked as expected (no special commands/etc to get I2C working).
I am using a shield that connects to the I2C bus through A4/A5 (according to the schematic the SDA/SCL lines are connected to A4/A5 as well). You could try using A4/A5 instead, but I doubt you will see different results. Are you sure you don't have SDA/SCL swapped?
I don't know if this is the problem, but my understanding is that the Edison already has pullup resistors on I2C, so it may be pulled up to hard.
Thanks, I got the I2C to "work" using A4/A5. Not sure why SDA/SCL on the digital pin jumper doesn't work. I can read the I2C address of the sensor most of the time, but often it still reports no I2C device. In those cases where the Edison can read the I2C addresses of the sensors, I am not getting any data from the sensors. Maybe there is too high (or low?) a pullup resistance. How can I set the internal pullups (or turn them off) on the Arduino breakout board?
I would suggest that a sample Edison sketch showing use of I2C (and SPI, for that matter) on the Arduino breakout board might be useful to a lot of people struggling as I am. Or maybe it's just me!
I turns out that there are two I2C ports on the Edison but only one is currently configured for operation in the Edison Arduino IDE, I2C6 on A4/A5 or jumper J17-7/J17-9 on the mini breakout board. The other, I2C1 is on digital SDA/SCL on the Arduino Breakout board (J17-8/J18-6 on the mini breakout board) and without a software change to allow more than one I2C port will not work. Fortunately, this software change is straightforward to implement so both are practically available.
Now, how does one change the pullup resistance on the GPIO pins and the SDA/SCL ports?
What'd you have to do to get A4/A5 working? I'm working with an MPU6050 and having essentially the same problem- no device detected. However, poking at I2C6 leads to nasty crashes, even just using i2cdetect. Here's one from i2cset:
root@Tesla:~# i2cset 6 0x69 0x6B 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will write to device file /dev/i2c-6, chip address 0x69, data address
0x6b, data 0x00, mode byte.
Continue? [Y/n] y
[ 1126.475346] i2c-designware-pci 0000:00:09.1: ===== REGISTER DUMP (i2c) =====
[ 1126.475465] i2c-designware-pci 0000:00:09.1: DW_IC_CON: 0x65
[ 1126.475541] i2c-designware-pci 0000:00:09.1: DW_IC_TAR: 0x69
[ 1126.475614] i2c-designware-pci 0000:00:09.1: DW_IC_SS_SCL_HCNT: 0x2f8
[ 1126.475687] i2c-designware-pci 0000:00:09.1: DW_IC_SS_SCL_LCNT: 0x37b
[ 1126.475761] i2c-designware-pci 0000:00:09.1: DW_IC_FS_SCL_HCNT: 0x87
[ 1126.475833] i2c-designware-pci 0000:00:09.1: DW_IC_FS_SCL_LCNT: 0x10a
[ 1126.475906] i2c-designware-pci 0000:00:09.1: DW_IC_INTR_STAT: 0x0
[ 1126.475978] i2c-designware-pci 0000:00:09.1: DW_IC_INTR_MASK: 0x246
[ 1126.476051] i2c-designware-pci 0000:00:09.1: DW_IC_RAW_INTR_STAT: 0x10
[ 1126.476124] i2c-designware-pci 0000:00:09.1: DW_IC_RX_TL: 0x20
[ 1126.476196] i2c-designware-pci 0000:00:09.1: DW_IC_TX_TL: 0x20
[ 1126.476268] i2c-designware-pci 0000:00:09.1: DW_IC_ENABLE: 0x1
[ 1126.476340] i2c-designware-pci 0000:00:09.1: DW_IC_STATUS: 0x2
[ 1126.476412] i2c-designware-pci 0000:00:09.1: DW_IC_TXFLR: 0x2
[ 1126.476484] i2c-designware-pci 0000:00:09.1: DW_IC_RXFLR: 0x0
[ 1126.476555] i2c-designware-pci 0000:00:09.1: DW_IC_TX_ABRT_SOURCE: 0x0
[ 1126.476627] i2c-designware-pci 0000:00:09.1: DW_IC_DATA_CMD: 0x0
[ 1126.476698] i2c-designware-pci 0000:00:09.1: ===============================
[ 1126.476802] CPU: 0 PID: 311 Comm: i2cset Tainted: G W O 3.10.17-poky-edison+ #1
[ 1126.476807] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 466 2014.06.23:19.20.05
[ 1126.476814] task: f5d8a6f0 ti: f5c2e000 task.ti: f5c2e000
[ 1126.476875] Stack:
[ 1126.476944] Call Trace:
[ 1126.477375] Code: b3 ff ff 89 f8 09 d0 80 ce 04 83 ff 02 0f 44 c2 8b 15 54 8b b0 c1 89 82 00 b3 ff ff f7 c6 00 02 00 00 74 14 e8 c7 f6 0a 00 56 9d <83> c4 04 5b 5e 5f
5d c3 90 8d 74 26 00 56 9d e8 b1 f2 0a 00 83
[ 1126.477400] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G W O 3.10.17-poky-edison+ #1
[ 1126.477405] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 466 2014.06.23:19.20.05
[ 1126.477413] task: f6c83d30 ti: f6e1c000 task.ti: f6e1c000
[ 1126.477474] Stack:
[ 1126.477542] Call Trace:
[ 1126.477747] Code: 8b 42 08 a8 08 75 24 31 c9 8d 42 08 89 ca 0f 01 c8 0f ae f0 89 f6 89 e0 25 00 e0 ff ff 8b 40 08 a8 08 75 07 b1 01 89 f0 0f 01 c9 <85> 1d 58 dd b3 c1 75 0d 8d 55 f0 b8 05 00 00 00 e8 8d 34 d9 ff
[ 1126.478384] i2c-6: recovery ignore
More than happy to hear that I'm being stupid. Any thoughts on pinning down where that's happening?
Somewhat better trace:
[ 1402.746400] ------------[ cut here ]------------
[ 1402.746446] WARNING: at /data/jenkins_worker/workspace/edison-weekly/linux-kernel/drivers/i2c/busses/i2c-designware-core.c:1236 i2c_dw_xfer+0x1d2/0x5b0()
[ 1402.746463] Device: i2c-designware-pci
[ 1402.746463] controller timed out
[ 1402.746479] Modules linked in: usb_f_acm u_serial g_multi libcomposite bcm_bt_lpm bcm4334x(O)
[ 1402.746545] CPU: 0 PID: 316 Comm: i2cset Tainted: G W O 3.10.17-poky-edison+ #1
[ 1402.746560] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 466 2014.06.23:19.20.05
[ 1402.746575] f5c2fd58 f5c2fd58 f5c2fd20 c18614b0 f5c2fd48 c123e6fe c1a8e450 f5c2fd74
[ 1402.746634] 000004d4 c1612fc2 c1612fc2 f5c16400 f5c2fe18 f5c16424 f5c2fd60 c123e753
[ 1402.746690] 00000009 f5c2fd58 c1a8e450 f5c2fd74 f5c2fd94 c1612fc2 c1a8e474 000004d4
[ 1402.746747] Call Trace:
[ 1402.746784] [<c18614b0>] dump_stack+0x16/0x18
[ 1402.746816] [<c123e6fe>] warn_slowpath_common+0x5e/0x80
[ 1402.746843] [<c1612fc2>] ? i2c_dw_xfer+0x1d2/0x5b0
[ 1402.746868] [<c1612fc2>] ? i2c_dw_xfer+0x1d2/0x5b0
[ 1402.746895] [<c123e753>] warn_slowpath_fmt+0x33/0x40
[ 1402.746922] [<c1612fc2>] i2c_dw_xfer+0x1d2/0x5b0
[ 1402.746951] [<c14b388c>] ? vsnprintf+0x2bc/0x390
[ 1402.746980] [<c160d6b5>] __i2c_transfer+0x55/0x70
[ 1402.747009] [<c160e49d>] i2c_transfer+0x4d/0xc0
[ 1402.747035] [<c14b39ea>] ? snprintf+0x1a/0x20
[ 1402.747063] [<c160e7d2>] i2c_smbus_xfer+0x222/0x5d0
[ 1402.747101] [<c12e8ee6>] ? unlock_page+0x46/0x50
[ 1402.747130] [<c1303258>] ? __do_fault+0x3a8/0x4a0
[ 1402.747159] [<c14b5b22>] ? _copy_from_user+0x42/0x60
[ 1402.747186] [<c1610308>] i2cdev_ioctl_smbus+0x148/0x280
[ 1402.747218] [<c155ac3d>] ? device_for_each_child+0x4d/0x70
[ 1402.747245] [<c16107f9>] i2cdev_ioctl+0x49/0x1e0
[ 1402.747271] [<c1305d6b>] ? handle_mm_fault+0xbb/0x110
[ 1402.747297] [<c16107b0>] ? i2cdev_ioctl_rdrw.isra.7+0x210/0x210
[ 1402.747323] [<c132a616>] do_vfs_ioctl+0x2f6/0x540
[ 1402.747353] [<c145e48a>] ? inode_has_perm.isra.41.constprop.78+0x3a/0x50
[ 1402.747381] [<c145e527>] ? file_has_perm+0x87/0x90
[ 1402.747409] [<c1324601>] ? follow_dotdot+0x111/0x140
[ 1402.747435] [<c1324834>] ? putname+0x24/0x40
[ 1402.747463] [<c145e8ec>] ? selinux_file_ioctl+0x4c/0xf0
[ 1402.747489] [<c132a8c0>] SyS_ioctl+0x60/0x80
[ 1402.747520] [<c1866e78>] syscall_call+0x7/0xb
[ 1402.747542] ---[ end trace 854e043acc15505c ]---
I also have problems in detecting a ADXL345 accelerometer using i2c-6 the minibreakout board and the mraa library. On the same channel, at a different address I have am Aadwark I2C USB host (a device used to monitor the I2C protocol). With the I2C monitor is also configured as a slave and is communicating correctly with the edison, so the HW setup is correct as one of the devices can comunicate. For the moment my conclusion was that the i2c clock speed might be too big for my sensor.
The Edison runs the i2c clock a 400Mhz. I tested the same setup with an Arduino Uno that runs the i2c clock at 100Mz and with the uno I was able to detect the accelerometer.
For the moment I was not able to find a way to change the i2c clock speed in order to see that my supposition is correct.
Any thoughts on this are welcomed
@gcondra: AFAIKT i2c6 is not exported on the Arduino breakout board. It looks like i2c6 is just used to control pullups, etc.
@ovicin: I'm sure you mean 100/400khz, not Mhz. Are you using some sort of level shifter (or 1.8V logic levels) on the breakout board. The breakout board doesn't include level shifters, and will not work with 3.3V logic.
I also tried to get an MPU6050 working on i2c1 on the Ardunio breakout board last night without success, so I would be interested in hearing any solutions. I was trying to use the mraa python library. I'm a bit confused by all the different methods of communicating to devices and what you need to do to configure I2C in each case. E.g. is using the mraa python library as easy as the examples (no need to configure the I2C bus pullups, etc)?
faceplant yes I meant Khz, sorry. I have 2 different devices on the same channel and with one of them I can communicate so the pull-ups and all the HW setup is correct and yes using the mraa library is as easy as in the example, there is no need to make additional settings.
I missed the connection between i2c6 and the muxes at the top of sheet 6 on the schematic, so i2c6 is supported on the Arduino breakout board. That still doesn't explain why i2c1 is not working as expected with some devices.
In the end in my case I was able to communicate with the ADXL345 accelerometer after changing the I2C clock speed to 100kHz. The way I did was updating the linux i2c-designware* driver to work all the time at 100kHz, recompiled the kernel and generating a new image.
Here are the steps to do it:
On a Linux machine (I used a Debian 7.7) install the following prerequisites:
sudo apt-get install build-essential git diffstat gawk chrpath texinfo libtool gcc-multilib
tar xvf edison-src.tgz
5-6 hours later
bitbake -c devshell linux-yocto
change the store_mode() function in drivers/i2c/busses/i2c-designware-core.c to set in all the cases the speed to STD
commit the changes and create a patch
git add -A
git commit -m "updates"
git-format-pach -1 <sha key of the commit>
copy the patch file to
/edison-src/device-software/meta-edison/recipes-kernel/linux/filesand rename it in order to replace the file that is already there
The files to be flashed are now in build/toFlash
That's great! Two questions:
1/ Do you experience the same crashes that I do when you use i2cdetect on bus 6? Since my part is supposed to be able to handle 400khz I'm wondering if we're hitting the same issue.
2/ Any chance you could post the patch? I'd like to eliminate as many sources of error as I can as I try to repro.
If this turns out to be a problem I'll probably make a change allowing this to be settable via module params and see if it can go upstream- no sense in everybody wanting to use an IMU having a custom kernel.
The ADXL345 should definitely be able to run at 400khz. If there really is a problem running it at 400khz on the Edison I would hate to just patch around it and run it at 100khz.
FWIW I tried a MPU9150 breakout board last night with the same results. I tried connecting it to both the A4/A5 and SDA/SCL headers with the same results. I also tried both with and without the commands to enable I2C6. I did see one kernel crash as you showed previously when detecting on I2C6, but mostly it just listed an empty table.