Project

General

Profile

Usage of I2C1 to connect external peripheral

Added by Raja Vankam over 12 years ago

Hi,

I am trying to use the I2C1 to communicate to the slave.

To probe the signals on Mity board, i am planning to change the pin mux for I2C1 from
mii1_crs.i2c1_sda to uart0_ctsn.i2c1_sda, similarly for scl in file board-mityarm335x.c.

Is the configuration allowed? Where to set the slave address for my need?

Regards,
Raja.


Replies (13)

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Hi,

Code i have used to access is mentioned below:

fd = open(filename, O_RDWR);
ioctl(fd, I2C_SLAVE, addr);
err = write(fd, buf, 5);

Open and ioctl with I2C slave are success. But write gives an error and the error number is: EREMOTEIO.

Could you please let me know any other configuration more i need to do?

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Sorry i missed to mention file name details.
filename = /dev/i2c-2.

RE: Usage of I2C1 to connect external peripheral - Added by Tim Iskander over 12 years ago

Raja
The EREMOTEIO error comes from drivers/i2c/busses/i2c-omap.c and is because there is no Ack from
bus request.
Unless I misunderstand what you are doing, I don't think you can just change the pin muxing around.
The pin muxing is set-up to reflect the layout of the board and if you move the i2c1 sda signal to another
pin it will not work.

cheers
/Tim

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Hi Tim,

In Mity arm board I2C1 is configured on mii1_crs. pin and in Am335x based board same I2c1 is on spi0_d1 pin. I just want to know whether i can change to uart pin mux and probe on expansion connector.
this is to make sure that i am able to access the bus.

By seeing board file of Mityarm, i understood that it is used to read factory config. But the same is given to base board for another device access.

I tried with both I2c0(J700) and I2c1 but the result is same as error. I have not yet connected any slave device to the board.

Could you pls let me know anything need to be changed the way i am accessing and writing to I2C.

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Hi Tim,

Gentle reminder about the above response.

Could you please let me know how to go ahead.

Regards,
Raja.

RE: Usage of I2C1 to connect external peripheral - Added by Tim Iskander over 12 years ago

Raja
You can use the i2c utilties to test the bus. The output below is from scanning both I2C buses.
root@mityarm-335x:~# i2cdetect -y -a -r 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
root@mityarm-335x:~# i2cdetect -y -a -r 2
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- 12 -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: UU 51 52 53 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

The code snippet you show looks basically ok.
If I understand what you are asking...
The I2C buses currently are used as follows (in the CL MityARM-335X Dev Kit)
I2C0 --> J700 expansion connector and module power monitor (U101) [ The sh_modpwr script reads U101 for example ]
I2C1 --> Factory configuration PROM (U5 on SOM), PMIC aux interface (U8 on SOM), and DVI driver chip (U400 on devkit board)
I2C2 --> PMIC main interface (U8 on SOM)

I2C0 is only available on 1 set of pins
I2C1 is available on a dedicated set of pins, or can usurp SPI0_CS0/SPI0_D1 OR UART1_RXD/TXD OR UART0_CTS/RTS
I2C2 I highly recommend you leave alone!

If you re-assign pins for the I2C interface, be aware of the following...
1 - You MUST change the pin mux settings for port that used to be the I2Cx interface (can't have 2 sets of pins running the interface).
2 - Be aware that devices that are currently connected to an I2C bus via exiting pinmux settings will become unavailable if you change the pin mux settings.

If you have not connected a device to the bus, then you will not be able to write to it and the bus will hang. You can try talking to the ADC part on I2C0 at address 0x48, which is the ADS1000 ADC for power monitoring.

cheers
/Tim

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Hi Tim,

Thanks for the reply.

Even my understanding is almost similar. But earlier I have tried with out connecting slave. Now I have connected the slave and still the error number is same and not able to write data to I2C. But opening device is successful.

I have used teh utility i2cdetect and the pattern for I2C2 is as below:

[88.802061] i2c aDAP:2
0 1 2 3 [88.804978] i2c slave:0x0
-
-
-
00: -- -- [] i2c slave: 0x3
10: -- -- 12 -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: UU 51 52 53 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

I tried to use slave address as: 0x01.

I have changed the pin mux settings in board-Mityarm.c as below

static struct pinmux_config i2c1_pin_mux[] = {
    /*{"mii1_crs.i2c1_sda",    AM33XX_SLEWCTRL_SLOW | AM33XX_PULL_ENBL |
                AM33XX_INPUT_EN | AM33XX_PIN_OUTPUT},
    {"mii1_rxerr.i2c1_scl",    AM33XX_SLEWCTRL_SLOW | AM33XX_PULL_ENBL |
                AM33XX_INPUT_EN | AM33XX_PIN_OUTPUT},*//*Commented for testing*/
{"uart0_ctsn.i2c1_sda",    AM33XX_SLEWCTRL_SLOW | AM33XX_PULL_ENBL |
                AM33XX_INPUT_EN | AM33XX_PIN_OUTPUT},
    {"uart0_rtsn.i2c1_scl",    AM33XX_SLEWCTRL_SLOW | AM33XX_PULL_ENBL |
                AM33XX_INPUT_EN | AM33XX_PIN_OUTPUT},
    {NULL, 0},
};

Do i have to change the "mityarm335x_i2c1_boardinfo" also to include another slave?

Could you please let me know what could be wrong to give this error?

Regards,
Raja.

RE: Usage of I2C1 to connect external peripheral - Added by Michael Williamson over 12 years ago

Hi Raja,

Can you please post the full command lines for your output?

There are actually 3 I2C buses in play.

I2C0 is connected to ADS1000 (address 0x48) and port J700 on the DevKit Host board. It shows up as /dev/i2c-1 and is accessed with i2cdetect -y -a -r 1.

I2C1 is connected to the TFP410 (DVI controller, address 0x38) on the DevKit Host board, a 24AA02 (EEPROM, address 0x50-0x57) and the TPS65910 PMIC Smart Reflex control port (address 0x12) on the MityARM-3359 SOM. It shows up as /dev/i2c-2 and is accessed with i2cdetect -y -a -r 2.

I2C2 is connected to the standard control port on the TPS65910 PMIC (address 0x2D) on the MityARM-3359 SOM. It shows up as /dev/i2c-3 and is accessed with i2cdetect -y -a -r 3.

I would recommend using I2C0. You could use J700 to get access to it using a Hirose connector. You could remux I2C1 (the PMIC is currently not controlled through the Smart Reflex port, but that will likely change in the future) if you don't require using the DVI controller or you configure it in u-Boot to power up the DVI chip prior to loading in your kernel. After that is done your change should work for the pinx on J502 (EXPANSION0_TX/RX). Make sure that the pin_mux settings are defined for that mode in the mux33xx.c file (and check your boot messages with dmesg) to make sure the mux values are getting configured correctly.

-Mike

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Hi Mike,

Thanks for your response.

I am using I2C1 and using from application as /dev/i2C-2. This change of pin mux is only for my testing. In the final board we will be using the same pin mux used in the evaluation board. We are not using DVI controller so i will take out that as being used option.

I have set the slave address as 0x01.

During write, "buf" contains, 0x01(register), 0x55 (data).

I this you are looking for command lines. I am attaching log file of booting for your reference. I have not seen any error indication.

Over all i wanted to know to use another slave on I2C1 apart from Factory eeprom, do i have to add the slave information in board_mityarm...c file keeping aside pin mux details?

Regards,
Raja.

RE: Usage of I2C1 to connect external peripheral - Added by Michael Williamson over 12 years ago

Can you post your source code for the I2CTest (including the value of addr) and provide a specification to the device you are communicating with (part number, etc)? You are sending a buffer size of 5 down, are the remaining 3 bytes supposed to be returned in a read call?

There are several I2C protocols (smbus, etc.) that you can use for I2C communication. Some require the use of an i2cdevice.h type wrappers. You might check the documentation here and we've made heavy use of this header/helper for user space access to I2C devices here.

Normally, you don't have to specify I2C clients in the kernel if you are going to use the i2c device (/dev/i2c-2) to communicate with it. You only need to call out the slave devices in the kernel if you want the kernel to explicitly communicate with the device. As long as you enable the i2c bus controller and the pin-mux for 2 wires that should be all that is required in the kernel.

-Mike

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Hi Mike,

Thanks for the information.

I will check on the details provided by you.

Regards,
Raja.

RE: Usage of I2C1 to connect external peripheral - Added by Raja Vankam over 12 years ago

Hi Mike,

I am coming back to you after long time. we have created setup with the slave connected on mityarm.

Attaching application code for your reference.

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<linux/i2c.h>
#include<linux/i2c-dev.h>

#include<errno.h>
#include<unistd.h>
int err;
char addr = 0x01;//Register addr
char adapter_no = 2;//I2C1 is used and slave address: 0x01
char arr10= {0x01, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
char RcvArr10;
char filename20;
int errval;

snprintf(filename, 19, "/dev/i2c-%d", adapter_no);

fd = open(filename, O_RDWR);

if(fd < 0) {
printf("Device opening error\n");
}

err = ioctl(fd, I2C_SLAVE, addr);
if(err < 0)
printf("error I2C slave address set: %d\n", err);

/*Writing data to I2C*/
err = write(fd, arr, 1);
errval = errno;
if(err) {
printf("write failed:%d, %d\n", err, errval);
switch(errval) {
case EREMOTEIO:
printf("EREMOTEIO\n");
break;
case EREMOTE:
printf("EREMOTE\n");
break;
default:
printf("some other error\n");
break;
}
}

err = read(fd, RcvArr, 1);
errval = errno;
if(err) {
printf("read bytes:%d, errno:%d,\n", err, errval);
}
close(fd);
return 0;
}

Open and slave address are success. But I always get the error as EREMOTEIO after write.
Alternatively I tried using IOCTL with I2C_RDWR. The Code is attached below.

unsigned long *funcs;
err = ioctl(fd, I2C_FUNCS, &funcs);
printf("funcs :%d\n", err);

struct i2c_rdwr_ioctl_data msgdata;
struct i2c_msg msgs[2];
unsigned char ret = 0;
unsigned int data = 0x0001;
msgdata.nmsgs = 2;
msgs[0].addr = 0x01;
msgs[0].len = 1;
msgs[0].buf = &data;
msgs[0].flags = 0;
msgs[1].addr = 0x01;
msgs[1].len = 1;
msgs[1].buf = &ret;
msgs[1].flags = I2C_M_RD;
msgdata.msgs = msgs;
err = ioctl(fd, I2C_RDWR, &msgdata);
errval = errno;
printf("write :%d, %d %d\n", err, errval, ret);

The result is same and error as well.

I tried to use smbus calls on your suggestion but it gives compilation error for i2c_smbus_write_byte_data. I located this function in linux/i2c.h and included the header file. Even i could not get out of error. Do i have to modify the I2c-dev.h as per the link mentioned above

I need to find out what is really going wrong.
Your quick response is appreciated.

RE: Usage of I2C1 to connect external peripheral - Added by Michael Williamson over 12 years ago

The error you are seeing is from the I2C device not seeing the proper ACK response from the I2C slave device when it issues the request.

Can you get a scope on the I2C lines and set a trigger during either of the transactions above?

Also, what device are you itnerfacing with?

-Mike

    (1-13/13)
    Go to top
    Add picture from clipboard (Maximum size: 1 GB)