I2C crashes, can't use e.g. LCD-RGB

Hi,

I’m trying to make Edison work with the Arduino Breakout board + Grove adapter + Grove-LCD RGB Backlight board. The LCD works as an I2C device, and it’s one of the examples in Edison’s mraa code.

I can’t make that work, seems like the i2c-designware-pci module crashes (see log below). Not sure if it’s a resin system’s problem, I basically use the same hardware as in this instructable (software is pretty much the same just using Intel’s own image, instead of resin’s).

Here’s the repo of the resin docker used.

The error message I get:

terminate called after throwing an instance of 'std::runtime_error'                                                            
  what():  upm::Jhd1313m1::Jhd1313m1(int, int, int): Unable to initialise the LCD controller                                   
Aborted                                                                                                                        

The kernel log from dmesg:

[   47.155146] ------------[ cut here ]------------
[   47.155194] WARNING: at /var/lib/yocto/edison/build/production/work/edison-poky-linux/linux-yocto/3.10.17+gitAUTOINC+6ad20f0
49a_c03195ed6e-r0/linux/drivers/i2c/busses/i2c-designware-core.c:1236 i2c_dw_xfer+0x1d2/0x5b0()
[   47.155212] Device: i2c-designware-pci
controller timed out
[   47.155228] Modules linked in: xt_connmark iptable_mangle usb_f_acm u_serial g_multi libcomposite bcm_bt_lpm bcm4334x(O)
[   47.155302] CPU: 0 PID: 596 Comm: python Tainted: G        W  O 3.10.17-yocto-standard #1
[   47.155317] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 466 2014.06.23:19.20.05
[   47.155332]  f36a9d58 f36a9d58 f36a9d20 c1958c77 f36a9d48 c123e92e c1bf5700 f36a9d74
[   47.155390]  000004d4 c16cac62 c16cac62 f5c3d800 f36a9e18 f5c3d824 f36a9d60 c123e983
[   47.155445]  00000009 f36a9d58 c1bf5700 f36a9d74 f36a9d94 c16cac62 c1bf5724 000004d4
[   47.155502] Call Trace:
[   47.155538]  [<c1958c77>] dump_stack+0x16/0x18
[   47.155569]  [<c123e92e>] warn_slowpath_common+0x5e/0x80
[   47.155597]  [<c16cac62>] ? i2c_dw_xfer+0x1d2/0x5b0
[   47.155623]  [<c16cac62>] ? i2c_dw_xfer+0x1d2/0x5b0
[   47.155650]  [<c123e983>] warn_slowpath_fmt+0x33/0x40
[   47.155677]  [<c16cac62>] i2c_dw_xfer+0x1d2/0x5b0
[   47.155706]  [<c16c5095>] __i2c_transfer+0x55/0x70
[   47.155733]  [<c16c5e7d>] i2c_transfer+0x4d/0xc0
[   47.155760]  [<c16c61b2>] i2c_smbus_xfer+0x222/0x5d0
[   47.155792]  [<c126c13b>] ? update_rq_clock.part.74+0x12b/0x150
[   47.155825]  [<c12c6491>] ? tracing_is_on+0x11/0x30
[   47.155855]  [<c1565b82>] ? _copy_from_user+0x42/0x60
[   47.155882]  [<c16c7ce8>] i2cdev_ioctl_smbus+0x148/0x280
[   47.155912]  [<c1961825>] ? sub_preempt_count+0x55/0xe0
[   47.155939]  [<c195dff5>] ? _raw_spin_lock_irqsave+0x25/0x30
[   47.155966]  [<c16c81d9>] i2cdev_ioctl+0x49/0x1e0
[   47.155993]  [<c12636f7>] ? hrtimer_try_to_cancel+0x37/0xf0
[   47.156022]  [<c16c8190>] ? i2cdev_ioctl_rdrw.isra.7+0x210/0x210
[   47.156049]  [<c132b376>] do_vfs_ioctl+0x2f6/0x540
[   47.156078]  [<c150a5fa>] ? inode_has_perm.isra.41.constprop.78+0x3a/0x50
[   47.156105]  [<c150a697>] ? file_has_perm+0x87/0x90
[   47.156134]  [<c1263200>] ? hrtimer_get_res+0x40/0x40
[   47.156161]  [<c150aa5c>] ? selinux_file_ioctl+0x4c/0xf0
[   47.156187]  [<c132b620>] SyS_ioctl+0x60/0x80
[   47.156216]  [<c195e738>] syscall_call+0x7/0xb
[   47.156237] ---[ end trace d74811bc5a47ec94 ]---
[   47.156259] i2c-designware-pci 0000:00:09.1: ===== REGISTER DUMP (i2c) =====
[   47.156339] i2c-designware-pci 0000:00:09.1: DW_IC_CON:               0x65
[   47.156412] i2c-designware-pci 0000:00:09.1: DW_IC_TAR:               0x3e
[   47.156484] i2c-designware-pci 0000:00:09.1: DW_IC_SS_SCL_HCNT:       0x2f8
[   47.156556] i2c-designware-pci 0000:00:09.1: DW_IC_SS_SCL_LCNT:       0x37b
[   47.156628] i2c-designware-pci 0000:00:09.1: DW_IC_FS_SCL_HCNT:       0x87
[   47.156700] i2c-designware-pci 0000:00:09.1: DW_IC_FS_SCL_LCNT:       0x10a
[   47.156772] i2c-designware-pci 0000:00:09.1: DW_IC_INTR_STAT:         0x0
[   47.156842] i2c-designware-pci 0000:00:09.1: DW_IC_INTR_MASK:         0x246
[   47.156914] i2c-designware-pci 0000:00:09.1: DW_IC_RAW_INTR_STAT:     0x10
[   47.156986] i2c-designware-pci 0000:00:09.1: DW_IC_RX_TL:             0x20
[   47.157057] i2c-designware-pci 0000:00:09.1: DW_IC_TX_TL:             0x20
[   47.157128] i2c-designware-pci 0000:00:09.1: DW_IC_ENABLE:            0x1
[   47.157198] i2c-designware-pci 0000:00:09.1: DW_IC_STATUS:            0x2
[   47.157268] i2c-designware-pci 0000:00:09.1: DW_IC_TXFLR:             0x2
[   47.157339] i2c-designware-pci 0000:00:09.1: DW_IC_RXFLR:             0x0
[   47.157409] i2c-designware-pci 0000:00:09.1: DW_IC_TX_ABRT_SOURCE:    0x0
[   47.157479] i2c-designware-pci 0000:00:09.1: DW_IC_DATA_CMD:          0x0
[   47.157549] i2c-designware-pci 0000:00:09.1: ===============================
[   47.157616] sending NMI to all CPUs:
[   47.157639] NMI backtrace for cpu 0
[   47.157651] CPU: 0 PID: 596 Comm: python Tainted: G        W  O 3.10.17-yocto-standard #1
[   47.157656] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 466 2014.06.23:19.20.05
[   47.157663] task: f5db26f0 ti: f36a8000 task.ti: f36a8000
[   47.157671] EIP: 0060:[<c12213bb>] EFLAGS: 00000206 CPU: 0
[   47.157684] EIP is at default_send_IPI_mask_logical+0x8b/0xd0
[   47.157691] EAX: 00000000 EBX: 03000000 ECX: c1c88660 EDX: fffff000
[   47.157697] ESI: 00000206 EDI: 00000002 EBP: f36a9d44 ESP: f36a9d34
[   47.157704]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[   47.157711] CR0: 8005003b CR2: b6e8b000 CR3: 31559000 CR4: 001007f0
[   47.157717] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[   47.157721] DR6: ffff0ff0 DR7: 00000400
[   47.157724] Stack:
[   47.157747]  00000800 00002710 f36a9e18 f5c3d824 f36a9d50 c12214d0 00002710 f36a9d60
[   47.157767]  c122163c c1b67531 f5c3d800 f36a9d94 c16caeca f64eb864 c1b8a18c 00000000
[   47.157787]  c1bccdb3 00000000 f5c3d898 00000001 00000000 f5c3d898 00000000 c1cd1b88
[   47.157790] Call Trace:
[   47.157807]  [<c12214d0>] default_send_IPI_all+0x60/0x70
[   47.157821]  [<c122163c>] arch_trigger_all_cpu_backtrace+0x4c/0x80
[   47.157835]  [<c16caeca>] i2c_dw_xfer+0x43a/0x5b0
[   47.157849]  [<c16c5095>] __i2c_transfer+0x55/0x70
[   47.157862]  [<c16c5e7d>] i2c_transfer+0x4d/0xc0
[   47.157875]  [<c16c61b2>] i2c_smbus_xfer+0x222/0x5d0
[   47.157892]  [<c126c13b>] ? update_rq_clock.part.74+0x12b/0x150
[   47.157910]  [<c12c6491>] ? tracing_is_on+0x11/0x30
[   47.157924]  [<c1565b82>] ? _copy_from_user+0x42/0x60
[   47.157938]  [<c16c7ce8>] i2cdev_ioctl_smbus+0x148/0x280
[   47.157952]  [<c1961825>] ? sub_preempt_count+0x55/0xe0
[   47.157965]  [<c195dff5>] ? _raw_spin_lock_irqsave+0x25/0x30
[   47.157979]  [<c16c81d9>] i2cdev_ioctl+0x49/0x1e0
[   47.157992]  [<c12636f7>] ? hrtimer_try_to_cancel+0x37/0xf0
[   47.158007]  [<c16c8190>] ? i2cdev_ioctl_rdrw.isra.7+0x210/0x210
[   47.158019]  [<c132b376>] do_vfs_ioctl+0x2f6/0x540
[   47.158033]  [<c150a5fa>] ? inode_has_perm.isra.41.constprop.78+0x3a/0x50
[   47.158047]  [<c150a697>] ? file_has_perm+0x87/0x90
[   47.158061]  [<c1263200>] ? hrtimer_get_res+0x40/0x40
[   47.158075]  [<c150aa5c>] ? selinux_file_ioctl+0x4c/0xf0
[   47.158087]  [<c132b620>] SyS_ioctl+0x60/0x80
[   47.158102]  [<c195e738>] syscall_call+0x7/0xb
[   47.158222] Code: b3 ff ff 89 f8 09 d0 80 ce 04 83 ff 02 0f 44 c2 8b 15 54 8b c8 c1 89 82 00 b3 ff ff f7 c6 00 02 00 00 74 1
4 e8 d7 03 0b 00 56 9d <83> c4 04 5b 5e 5f 5d c3 90 8d 74 26 00 56 9d e8 c1 ff 0a 00 83
[   47.158232] NMI backtrace for cpu 1
[   47.158247] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G        W  O 3.10.17-yocto-standard #1
[   47.158252] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 466 2014.06.23:19.20.05
[   47.158260] task: f6c8bd30 ti: f6e22000 task.ti: f6e22000
[   47.158269] EIP: 0060:[<c15ae58e>] EFLAGS: 00200046 CPU: 1
[   47.158281] EIP is at intel_idle+0x8e/0xe0
[   47.158288] EAX: 00000052 EBX: 00000040 ECX: 00000001 EDX: 00000000
[   47.158294] ESI: 00000052 EDI: c1cc0a08 EBP: f6e23f30 ESP: f6e23f18
[   47.158301]  DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[   47.158308] CR0: 8005003b CR2: b7251000 CR3: 01dcc000 CR4: 001007f0
[   47.158314] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[   47.158318] DR6: ffff0ff0 DR7: 00000400
[   47.158321] Stack:
[   47.158343]  00000006 00000002 00000001 c1cc0960 f7402400 c1cc0a08 f6e23f54 c16f7dd1
[   47.158364]  00000002 000002df f64ae593 0000000a f6e22000 c1cc0960 00000098 f6e23f74
[   47.158383]  c16f7f12 c1cc0960 00000001 f7402400 f6e22000 00000000 00000000 f6e23f7c
[   47.158386] Call Trace:
[   47.158408]  [<c16f7dd1>] cpuidle_enter_state+0x31/0xd0
[   47.158425]  [<c16f7f12>] cpuidle_idle_call+0xa2/0x220
[   47.158441]  [<c120821d>] arch_cpu_idle+0xd/0x30
[   47.158454]  [<c12846b5>] cpu_startup_entry+0x65/0x200
[   47.158469]  [<c194e6a7>] start_secondary+0x230/0x235
[   47.158590] 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 0
7 b1 01 89 f0 0f 01 c9 <85> 1d 58 09 cc c1 75 0d 8d 55 f0 b8 05 00 00 00 e8 5d e0 cd ff
[   47.159232] i2c-6: recovery ignore

Any suggestions?

Just tried it with the official 2.1 Yocto image for the Edison, and that runs the python script I tried to run totally fine. Thus it does look like a crash/bug in the resin image.

As a side-note, might be related, but not all digital pins can be used in the resin image. Every digital pin below 7 returns an error like:

>>> import mraa
>>> led = mraa.Gpio(4)
Traceback (most recent call last):                                              
  File "<stdin>", line 1, in <module>                                           
  File "/usr/local/lib/python2.7/site-packages/mraa.py", line 420, in __init__  
    this = _mraa.new_Gpio(*args)                                                
ValueError: Invalid GPIO pin specified 

With the official image, I could use any of the pins (tried with a grove LED on D2 - D8)

Just saying, because this these two issues show that the resin image clearly different somehow from the official one.

Hi there, yes indeed it doesn’t seem to work. Unfortunately this is one of the reasons the Edison is currently marked as experimental, we are working on removing the differences in our images, so hopefully very soon all the mraalib examples will work as expected.

Sorry for the inconvenience. I will post back here when I have more details and if I find a possible midterm hack to get it working.
cheers

Hi Shaun, thanks for the feedback! I was wondering what’s the difference between the images Was planning to dive into meta-resin a bit and compile one from scratch to see that, but probably at the moment I’ll just wait. Let me know if there’s anything I can test, though, more than happy!

So will wait to see if any new comment arrives pops up here. Cheers! (and you are doing awesome, just thought I tell you)

So looking around a bit, I noticed that the mraa lib relies on the debug_gpio to set the pin mode functionality. By default this is not mounted in the docker container.
However you can mount it by running this before you start your python script on the device.

mount -t debugfs nodev /sys/kernel/debug

This seems to allow me to run mraa.Gpio(4) with out getting the error you do. However it still doesnt appear to fix the LCD issue, but I don’t have the LCD to test for sure.

If you want to see the line in libmraa, you can see it here:

You know what, just tried it out and it works like a charm for both GPIO and the LCD! Brilliant! I was just about to dig into the Edison GPIO Muxing Guide because I thought it might be some pull-up resistor setting problem - and probably it was, the system couldn’t set the right default values before and now it can (so glad I don’t need to dig that doc more…)

Thanks a lot for the pointer! And now the start script in your blink makes complete sense too!

There might be still some unsolved issues, because turning the device back on today the RGB part was working while the display part seem to be borked (those are two different i2c devices on the same bus), so definitely need more testing. Still, it looks like being on the right path. :smile:

An interesting thing after trying it a bit more…

If I just use the mount option:

  • First boot: I2C is half-functional (RGB works, screen is mostly borked in a way, doesn’t really matter how, just it doesn’t work)
  • If env vars changed in the Resin dashboard and thus the application is restarted, from there it worked fine!
  • if reflashed with new app code while the box was running, it worked fine…

(in a nutshell, had to restart the application once after boot to make it work correctly)

That was annoying, so I went back to the Edison GPIO mux docs, took Example 4: Configure IO18/IO19 for I2C connectivity, and put that example (in a heavily modified form) in a shell script, which executes it as part of the Docker entrypoint.

Now it seems to be better on start. Looks like pretty much all the the I2C line seems to work well from the beginning. I guess I’ll need to include that script in future Edison/I2C projects. Made it so that it works without errors with Resin’s hot application restart (e.g. on env change).

That’s my weekend’s 2cents… Also, I’ve written up result of the original project in a blogpost.

Cheers! :smile:

Thanks for the interesting info. I will definitely be looking into this and figuring out how to make this a little less painful for those that venture here after you. Great work and really great that you got down so deep into this.
Cheers
Shaun

@imrehg I uses your project to build a demo, which you can find here: https://github.com/shaunmulligan/edison-starter-kit-python

I didn’t find that I needed the GPIO setup stuff. My LCD works on first start/boot with this demo. I think it may be due to doing a

udevadm trigger

in the docker-entrypoint.sh which allows i2c to be correctly added to /dev in the container. It would be great if you tested this on your setup and let me know if there is still an issue.
Thanks again for all the info.
Cheers
Shaun

Indeed, @shaunmulligan, tried that one, and the simplified docker-entrypoint seems to be working fine (did a couple of cold boots).

Thanks for the info this is really cool! (at least I’ve learned some more bash scripting from the other way:)

Well, I think I got to take that back.

udevadm trigger on its own (at least the way I’ve done in the script in the previous comment) does not seem to work. After a few cold boots, back to the borked I2C (signified by kinda half-shaded background on the first line of the LCD, even when characters are shown)

Reverted the last change back to the shell script and it works again. Am I missing anything else? is there any sleep needed, for example?

hmm… that is strange, I will have to do some more testing. You aren’t missing anything, I most likely didn’t test it thoroughly enough. I guess this will need some more digging. Glad at least your script will give us some insight. Thanks again for the info.