iMX6 i2c Communication

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX6 i2c Communication

4,877 Views
ritesh_panchal
Contributor I

I am using imx6qsabresd board.

I want to develop i2c based driver for camera sensor.

Can you provide user guide to develop i2c kernel module and C Application for i2c?

Labels (3)
0 Kudos
5 Replies

2,081 Views
igorpadykov
NXP Employee
NXP Employee

Hi Ritesh

one use existing driver as starting point, please refer to attached Linux Manual Chapter 14

OmniVision Camera Driver and sect.20.5 Using the I2C Interface i.MX53 System Development User’s

Guide (rev.1, 3/2011)

http://www.freescale.com/files/32bit/doc/user_guide/MX53UG.pdf

Linux Drivers tutorial

https://lwn.net/images/pdf/LDD3/ch01.pdf

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,081 Views
ritesh_panchal
Contributor I

Hi,

Thanks for the Reply.

But i want to Read & Write register of OV5640 connected on J9 on imx6qsabresd board. It uses I2C1 for Configuration.

If i modify ov5640.c file and add read & write any register API in ov5640_probe(). And compile linux kernel. I can read/write registers.

But i want to do the same using C application.

I an using Eclipse for Develop & Debug my application.

I have setup eclipse as per the link below.

http://developer.toradex.com/knowledge-base/hello-world-application-on-embedded-linux

http://janaxelson.com/eclipse5.htm

This is my below program.

#include <stdint.h>

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <linux/i2c-dev.h>

#include <linux/i2c.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/ioctl.h>

#include <fcntl.h>

#include <linux/kernel.h>

typedef unsigned char           u8;

typedef unsigned short          u16;

typedef unsigned int            u32;

typedef unsigned long long      u64;

typedef signed char             s8;

typedef short                   s16;

typedef int                     s32;

typedef long long               s64;

// I2C Linux device handle

int g_i2cFile;

// open the Linux device

void i2cOpen()

{

       g_i2cFile = open("/dev/i2c-1", O_RDWR);

       if (g_i2cFile < 0) {

            perror("i2cOpen");

            puts("I2C Open Failed");

            exit(1);

       }

       else

            puts("I2C Open Success");

}

// close the Linux device

void i2cClose()

{

       close(g_i2cFile);

}

// set the I2C slave address for all subsequent I2C device transfers

void i2cSetAddress(int address)

{

       if (ioctl(g_i2cFile, I2C_SLAVE, address) < 0) {

            perror("i2cSetAddress");

            puts("I2C Set Address Failed");

            exit(1);

       }

       else

            puts("I2C Set Address Success");

}

static s32 ov5640_write_reg(u16 reg, u8 val)

{

       u8 au8Buf[3] = {0};

       au8Buf[0] = reg >> 8;

       au8Buf[1] = reg & 0xff;

       au8Buf[2] = val;

       if (write(g_i2cFile, au8Buf, 3) < 0) {

            return -1;

       }

  return 0;

}

static s32 ov5640_read_reg(u16 reg, u8 *val)

{

       u8 au8RegBuf[2] = {0};

       u8 u8RdVal = 0;

       au8RegBuf[0] = reg >> 8;

       au8RegBuf[1] = reg & 0xff;

       if (2 != write(g_i2cFile, au8RegBuf, 2)) {

            puts("1");

            return -1;

       }

  else

       puts("2");

 

if (1 != read(g_i2cFile, &u8RdVal, 1)) {

       return -1;

  }

  else

       puts("4");

      

     *val = u8RdVal;

       printf("%d",u8RdVal);

       return u8RdVal;

}

int main(void) {

  u8 mode;

        puts("I2C Test Program");

        i2cOpen();

        i2cSetAddress(0x78);

        ov5640_read_reg(0x3100, &mode);

        printf("%d",mode);

        if(mode == 0x78)

        puts("Match");

        else

        puts("Not Match");

        i2cClose();

        return 0;

}

below is the Output of the Program

I2C Test Program                                                               

I2C Open Success                                                               

I2C Set Address Success                                                        

1                                                                              

0Not Match

So whats wrong with the code?

And is there any tutorial to access ov5640 using C Application?

0 Kudos

2,081 Views
ritesh_panchal
Contributor I

I just found that ov5640 i2c Address is 0x3C. 0x78 & 0x78 is for write and 0x79 is for read.

if i send 2cSetAddress(0x3C) command i got "i2cSetAddress: Device or resource busy" message.

if i remove ov5640_camera_mipi module than i successfully set 0x3C register.

But i got 0 when i try to read CHIP ID 0x300A & 0x300B.

ov5640_read_reg(0x300B, &value);

static s32 ov5640_read_reg(u16 reg, u8 *val)

{

  u8 au8RegBuf[2] = {0};

  u8 u8RdVal = 0;

  au8RegBuf[0] = reg >> 8;

  au8RegBuf[1] = reg & 0xff;

  write(g_i2cFile, au8RegBuf, 2);

  read(g_i2cFile, &u8RdVal, 1);

  *val = u8RdVal;

  printf("result=%d\n\r",u8RdVal);

  return u8RdVal;

}

Whats the problem?

whats the right API to read i2c address of ov5640.?

0 Kudos

2,081 Views
igorpadykov
NXP Employee
NXP Employee
0 Kudos

2,081 Views
ritesh_panchal
Contributor I

hello.

Its a useful link.

But can you tell me how to access register using write/read function or i2c_smbus_read_word_data/i2c_smbus_write_word_data functions?

or in my code what is missing?

0 Kudos