This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-J721E: I2C communication using C code

Part Number: PROCESSOR-SDK-J721E

Tool/software:

Hi,

    I tried to communicate with the I2C device in the J721e EVM Board(Common board) using C code. But I cannot access the device. I am attaching my code here.

void Config_value();                                                
int i2cfile = 0;                                                    
                                                                    
void main()                                                         
{                                                                   
        char *bus = "/dev/i2c-3"; // assigning a pointer to the path
                                                     
        //Opening the bus                            
        if((i2cfile = open(bus, O_RDWR)) < 0)        
        {                                            
                printf("Failed to open the bus. \n");
                exit(1);                     
        }                                    
        // Get I2C device,                   
        if(ioctl(i2cfile, I2C_SLAVE, 0x28)<0)
        {                                    
                printf("Error\n");           
                exit(1);                     
        }                                    
        printf("\nCommunication Started\n"); 
        Config_value();
}
void Config_value()                             
{                                               
        char i2cconfig[3] = {0};                
        i2cconfig[0] = 0x0E;//Configuration register 14
        i2cconfig[1] = 0x3F;                           
        write(i2cfile,i2cconfig,2);                    
}

After executing the above code I checked the register using the command "i2cget -f -y 3 0x22 0x0E b". The value is not changing.

I can change the value using "i2cset -f -y 3 0x22 0x0E 0x3F b". Slave address is 0x22.

Regards,

Rejin

  • Because of the holidays, responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience

  • Hi Rejin,

    You appear to be writing to address 0x28 instead of 0x22.

    Best,
    Jared

  • Hi Jared,

     when I give the address as 0x22, the code showing it as an error. I will show the code and output.

    void main()               
    {                         
            char *bus = "/dev/i2c-3"; // assigning a pointer to the path
                                                                        
            //Opening the bus                                           
            if((i2cfile = open(bus, O_RDWR)) < 0)                       
            {                                                           
                    printf("Failed to open the bus. \n");               
                    exit(1);                                            
            }                                                           
            // Get I2C device,                                          
            if(ioctl(i2cfile, I2C_SLAVE, 0x22)<0)                       
            {                                                           
                    printf("Error in assigning slave address\n");       
                    exit(1);                                            
            }                                                           
            printf("\nCommunication Started\n");                        
                                                                        
            Config_value();
    }
    

    This is the reason I gave 0x28. I tried with the address 0x24. I am confused which address I have to give 0x28 or 0x24. In schematic it is specified as 0x22. But why the error come when I gave the value as 0x22.

  • Hi Regin,

    Can you run i2cdetect on the relevant i2c bus?

    Best,
    Jared

  • Hi Jared,

    Here I am attaching screenshots for the i2cdetect.

    thanks in advance

    Regards,

    Rejin

  • Hi Rejin,

    I meant running something like:

    root@am69-sk:~# i2cdetect -y -r 0
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:                         -- -- -- -- -- -- -- -- 
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: 40 -- -- 43 -- -- -- -- UU 49 4a 4b -- -- -- -- 
    50: -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    70: -- -- -- -- -- -- -- --

    Additionally, what SDK version are you using?

    Best,
    Jared

  • Hi Jared,

    Sorry for the delay. I am attaching the screenshot of i2cdetect

    I am using SDK version 8.06.01

    I can access the USER LED (2 no's) and user switch assigned in this i2cbus through Linux user space.

    Regards,

    Rejin

  • Hi Rejin,

    Are you trying to access the device at 0x22? Are you able to?

    Best,
    Jared

  • Hi Jared,

    Sorry for the delay. Yes I tried with 0x22 but code show as error.

     

    Regards,

    Rejin

  • Hi Rejin,

    I don't think you can access the address if the device is already in use by something else. If you disable whatever driver currently owns the device, are you able to assign the address?

    Best,
    Jared

  • Hi Jared,

    I can change the user led status and get the user input from the i2c device in linux user space using the same address 0x22. Then why I can't change the status through C code. How to find which device is using the i2c device.

    Regards,

    Rejin

  • Hi Rejin,

    I retract my earlier statement about not being able to access the device if it's used by a kernel driver. But if you're curious, you can look at the device tree's compatible field if you want so see what driver is using the i2c device.

    What error code is the ioctl call outputting? I haven't had any issues with my own tests.

    Best,
    Jared

  • Hi Jared,

    I used ioctl function in C program and I got the result as -1. I think generally it will send -1 for error. I didn't get a specific number ie -2 or -3 like that.

    I have another memory card that came with the common board and I will post my result. Currently my memory card is modified to use all my LAN port (9 Nos). May be In that any other device is handling the I2C device.

    Regards,

    Rejin  

  • Hi Rejin,

    What device are you trying to access specifically? Is it the i2c gpio expander, specifically exp2 on the main_i2c0 bus? The driver for the gpio expander is: gpio-pca953x.c

    I rewrote my test and I am seeing that every device that is currently busy, I am unable to access. I don't think you can access the i2c device if the device is busy.

    Following is the test code:

    #include <stdlib.h>
    #include <stdio.h>
    
    #include <fcntl.h>
    #include <string.h>
    #include <unistd.h>
    
    #include <sys/ioctl.h>
    
    #include <linux/i2c-dev.h>
    
    int main(int argc, char *argv[])
    {
            int file;
            char filename[20];
    
            strcpy(filename, "/dev/i2c-");
            strcat(filename, argv[1]);
    
            printf("Opening: %s\n", filename);
            file = open(filename, O_RDWR);
    
            if (file < 0) {
                    printf("failed on file open\n");
                    exit(1);
            }
    
            int addr = (int) strtol(argv[2], NULL, 16);
    
            printf("Accessing slave: 0x%s\n", argv[2]);     
            if (ioctl(file, I2C_SLAVE, addr) < 0) {
                    printf("failed on slave access\n");
                    exit(1);
            }       
    
            return 0;
    }

    Commands executed:

    root@j721e-evm:~# i2cdetect -y -r 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:                         -- -- -- -- -- -- -- -- 
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    20: UU -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- 6d -- -- 
    70: 70 71 -- -- -- -- 76 --                         
    root@j721e-evm:~# ./test 1 22
    Opening: /dev/i2c-1
    Accessing slave: 0x22
    failed on slave access

    The reason your i2cget works is because you are using the -f (force) flag which will allow you to read the device even if it's busy.

    Additionally, you can't recompile the driver as a module and disable it without breaking the boot. If you want to set a gpio pin with a gpio-hog, you should do it in the device tree.

    Best,
    Jared

  • Hi Jared,

    I run the code that given above. But failed on slave access. I used the default memory card ie not modified one. But the error still exist.

    Regards,

    Rejin

  • Hi Rejin,

    I was saying that this is the expected and intended response. You shouldn't be able to access the device when it is busy.

    You will have to disable the driver that is controlling the device.

    The only reason i2cget works is because you are executing the command with the force (-f) flag.

    Best,
    Jared