Hello.
We are using Yocto and Timesys BSP to build our custom Linux BSP. (Kernel 3.0.15)
Our board is based on the Vybrid VF65GS10.
We want to access the temperature sensor (I2C) on our custom board from userspace.
What have we done;
- Updated BSP with correct I2C device address
- Verified similar Kernel output as for the devkit
- Verified SYSFS device present
- Verified dev entry present
But when we execute the userspace code, we cannot access the device at all.
Our Logic Analyzer shows that we try to send data on the I2C bus, but we always get NACK's regardless of reads or writes.
We suspect this is an issue with our BSP.
In particular, we have the following in our kernel configuration:
linux-timesys/3.0.15-r0/git/arch/arm$ less ../../.config | grep I2C
CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
# CONFIG_SENSORS_LIS3_I2C is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_MUX is not set
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
# I2C Hardware Bus support
# I2C system bus drivers (mostly embedded / system-on-chip)
# CONFIG_I2C_DESIGNWARE is not set
CONFIG_I2C_GPIO=y
CONFIG_I2C_IMX=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_PXA_PCI is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_XILINX is not set
# External I2C/SMBus adapter drivers
# CONFIG_I2C_DIOLAN_U2C is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set
# Other I2C/SMBus bus drivers
CONFIG_I2C_STUB=m
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
CONFIG_I2C_DEBUG_BUS=y
# I2C GPIO expanders:
# I2C RTC drivers
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
We have the ADT7410 I2C Temperature sensor (datasheet). We have grounded the A0, A1 pins to get 0x48 address set.
Same pins used for I2C as on the devkit, i.e. I2C0_SCLK & I2C0_SDA on our custom board.
From the board-twr-vf700.c file:
static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
{
//I2C_BOARD_INFO("sgtl5000", 0x0a),
I2C_BOARD_INFO("tsensor", 0x48),
},
};
Kernel shows output during boot;
..
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
ARC USBOTG Device Controller driver (1 August 2005)
mousedev: PS/2 mouse device common for all mice
snvs_rtc snvs_rtc.0: rtc core: registered snvs_rtc as rtc0
i2c /dev entries driver
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
..
SYSFS show registered device..
/ # ls /sys/bus/i2c/devices/
0-0048 i2c-0
Device exists..
/ # ls -la /dev/i2c-0
crw-rw---- 1 0 0 89, 0 Nov 26 2015 /dev/i2c-0
Userspace code:
#define I2C_BUS_NODE "/dev/i2c-0"
#define I2C_TEMP_SENSOR_ADDRESS 0x48
#define I2C_TEMP_LSB_REGISTER 0x01
..
// open the i2c device for communication
int file = open(I2C_BUS_NODE, O_RDWR);
if (file < 0)
{
log_error("I2C Could not be initialized correctly");
return;
}
// specify which i2c unit to communicate with
int ioResult = ioctl(file, I2C_SLAVE, I2C_TEMP_SENSOR_ADDRESS);
if (ioResult < 0)
{
log_error("I2C Slave Address could not be set correctly. Error Code %i", ioResult);
return;
}
int res = i2c_smbus_read_word_data(file, I2C_TEMP_LSB_REGISTER);
if (res < 0)
{
log_error("I2C Temperature could not be read, %i", res);
}
else
{
log_info("Temperature LSB. %i", res);
}
The i2c_smbus_read_word_data call returns -1 (EPERM).
Do we need to have a specialized kernel driver for each i2c chip we plan to use?
How can we verify our setup?
In the OOBE demo image, which kernel configuration was used to allow for communication with the touch_cr and sgtl5000?
Any hints or help would be greatly appreciated.
Regards
Andreas Eknes Lie
Solved! Go to Solution.
Hello Andreas,
If you have i2c-tools in your Yocto build, you can use i2cdetect -y <bus num> to scan the devices on the i2c bus in question.
Do you have the driver for the ADT7410 enabled in your kernel: CONFIG_ADT7410 ?
The config used for the 3.0.15 kernel in Yocto, we will assume the Dora branch, since 3.0.15 has since been removed and 3.13 now the default, can be reviewed here:
Given this is a custom hardware design - TWR-Vybrid VF6 based, correct? - there may be some additional i2c work required.
Regards,
Timesys Support
Hello again.
We finally made the i2c bus communication work as intended.
There is a design difference on our custom board that cause this issue.
For reference, the pad ctrl we added to the pin iomuxing (iomux-mvf.h) was PAD_CTL_ODE | PAD_CTL_DSE_20ohm (instead of 50ohm)
It was not enough to just add ODE (open drain enable) in our case.
I have to be honest here, i thought that i2c needed to be ODE. (http://www.i2c-bus.org/i2c-primer/how-i2c-hardware-works/)
But the kernel (and i2c bus) did work on the devkit, without the ODE flag set (and with 50ohm DSE).
The i2cdetect tool proved to be invaluable though, relieving me of doubts regarding userspace implementation.
Thanks for the help.
timesyssupport are you able to help here?