Hi all,
I am trying to interface a LCD display 2x16 with the Digi Connect ME 9210 through the PCA9554 I2C chip.
Environment:
-
Development platform: Digi ESP DEL-5.2 for Digi Embedded Linux 5.2
-
Linux Kernel configuration
Device Drivers
I2C support
I2C device interface (M)
Autoselect pertinent helper modules (Y)
I2C Hardware Bus support
Digi ns9360, ns921x (M)
GPIO Support (Y)
/sys/class/gpio… (sysfs interface) (Y)
PCA953x, PCA955x, and MAX7310 I/O ports (M) -
I2C LCD module: LCD display 2x16 + PCA9554 (connected to the SDA and SCL pins of the cme module)
-
An oscilloscope is connected to the SDA and SCL pins of the PCA9554 chip.
In the first time, I validated the i2c lcd display using an atmega8 micro controller configured as i2c master. In this configuration, I written successfully a “hello world” to the lcd display. My goal is to drive the LCD by the cme9210.
-
I found some information about 9210 I2C in the thread “Embedded Linux -> Development -> CME 9210 + RTC”.
-
The cme9210 don’t have the code to enable the I2C interface. So, I have based on the cme9215 machine code to patch the cme9210 machine code (file: kernel/linux/arch/arm/mach-ns9xxx/mach-cme9210js.c). I added somes debug traces to check it. Then, when the board starts, the I2C interface is well registered as shown in following debug messages messages:
file kernel/linux/arch/arm/mach-ns9xxx/mach-cme9210js.c:
Call ns9xxx_add_device_cme9210_i2c
file kernel/linux/arch/arm/mach-ns9xxx/ns921x_devices.c:
Configure clock
file kernel/linux/drivers/base/platform.c:
Adding device: success -
I loads successfully i2c-ns9xxx, i2c-core, pca953x and i2c-dev drivers. The /dev/i2c-0 device is well created. See debug messages above:
modprobe i2c-ns9xxx
dmesg
…
i2c-core: driver [dummy] registered
bus: ‘platform’: add driver i2c-ns9xxx
bus: ‘platform’: driver_probe_device: matched device i2c-ns9xxx with driver i2c-ns9xxx
i2c-ns9xxx i2c-ns9xxx: mapped I2C interface to virtual address0xc1078000
i2c-ns9xxx i2c-ns9xxx: I2C_NORMALSPEED: 100000
I2C adapter driver [i2c-ns9xxx] forgot to specify physical device
i2c-adapter i2c-0: adapter [i2c-ns9xxx] registered
i2c-ns9xxx i2c-ns9xxx: NS9XXX I2C adapter
…
modprobe pca953x
dmesg
…
bus: ‘i2c’: add driver pca953x
kobject: ‘pca953x’ (c06a0f80): kobject_add_internal: parent: ‘drivers’, set: ‘drivers’
bus: ‘i2c’: driver_probe_device: matched device 0-0020 with driver pca953x
bus: ‘i2c’: really_probe: probing driver pca953x with device 0-0020
pca953x 0-0020: probe
i2c-adapter i2c-0: master_xfer[0] W, addr=0x20, len=1
i2c-adapter i2c-0: master_xfer[1] R, addr=0x20, len=1
i2c-core: driver [pca953x] registered
…
modprobe i2c-dev
i2c /dev entries driver
i2c-core: driver [dev_driver] registered
i2c-dev: adapter [i2c-ns9xxx] registered as minor 0
ls -il /dev
…
47 crw-rw---- 1 root root 89, 0 Jan 1 00:13 i2c-0
…
lsmod
Module Size Used by Not tainted
i2c_dev 5988 0
pca953x 3168 0
i2c_ns9xxx 6656 0
i2c_core 20080 3 i2c_dev,pca953x,i2c_ns9xxx
…
ls -al /sys/bus/i2c/devices/0-0020/
drwxr-xr-x 4 root root 0 Jan 1 00:02 .
drwxr-xr-x 5 root root 0 Jan 1 00:06 …
lrwxrwxrwx 1 root root 0 Jan 1 00:18 driver -> …/…/…/…/…/bus/i2c/drivers/pca953x
drwxr-xr-x 3 root root 0 Jan 1 00:02 gpio
-r–r–r-- 1 root root 4096 Jan 1 00:18 modalias
-r–r–r-- 1 root root 4096 Jan 1 00:18 name
drwxr-xr-x 2 root root 0 Jan 1 00:18 power
lrwxrwxrwx 1 root root 0 Jan 1 00:18 subsystem -> …/…/…/…/…/bus/i2c
-rw-r–r-- 1 root root 4096 Jan 1 00:18 uevent
- I have implemented a simple C program “test.exe” to send a byte to the PCA9554. See example in the documentation kernel/linux/Documentation/i2c/dev_interface. Here is the main part of the code:
…
int test(void)
{
int file;
char* filename=“/dev/i2c-0”; /* I2C user device /
int addr = 0x40; / The I2C address */
char buf[4];
if ((file = open(filename, O_WRONLY)) < 0) {
// ERROR HANDLING; you can check errno to see what went wrong
fprintf(stderr, “Failed to open %s: %s”, filename, strerror(errno));
return(-1);
}
if (ioctl(file, I2C_SLAVE, addr) < 0) {
// ERROR HANDLING; you can check errno to see what went wrong
fprintf(stderr, “Failed to set %d: %s”, file, strerror(errno));
close(file);
return(-1);
}
buf[0] = 0x01;
buf[1] = 0x02;
if (write(file, buf, 2) < 0) {
/* ERROR HANDLING: i2c transaction failed */
fprintf(stderr, “Failed to write to %d: %s”, file, strerror(errno));
close(file);
return(-1);
}
close(file);
return(0);
}
…
-
When I launch the test.exe program, I can see several signals in the scope, probably the I2C initialization. The /dev/i2c-0 is opened successfully. But writing failed with error: “Failed to write to 3: Input/output error”. And all PCA9554 output pins (DB0 to DB7) are high (5V measured), which confirm that nothing have been writen.
-
I have tryied the smbus function “i2c_smbus_write_byte()” instead of the “write()” and encountered the same issue (Input/output error).
-
I saw a similar problem in the thread “Embedded Linux -> Development -> CME 9210 + RTC”, but cannot get the PCA9554 works.
I am very wondered by this issue. I have re-validated the LCD module with the atmega8 micro controller. I have also verifyied several times the kernel configuration, the C program code, electrical connexions between PCA9554 and the cme9210 module…
Does anyone port the PCA9554 on the cme9210 module? What have I missed? How can I use directly the class ns9xxx driver interface instead of the /dev/i2c-0
Please help me. I am very blocked. Don’t hesitate to ask further informations.