ov5693's v4l2 interface not supported in r28.2 ?

Hi:

I try to get image from ov5693 with v4l2 interface,but just get "select timeout"(after stream on ioctl),the test code will be appended after this.

I can use nvgstcapture-1.0 to preview,the nvcamerasrc and the nvarguscamerasrc all ok,so the connect

of ov5693 is ok.It seems the libs also ok.

And I can use this test code in my Imx6Q(freescale,nxp imx6q board) to get raw data(just modify 

iWidth,iHeight,PIX_FMT),may be I can say the function of this test code is ok? I simplied the test code

to use the driver’s default configuration.

so,where is the problem?

"v4l2-ctrl" can not be found in ubuntu16.04,so I installed it with "sudo apt-get install v4l-utils".

I cross compile the kernel,used the tegra18_defconfig,just let HZ to 1000.

[b]Did v4l2 interface not supported in r28.2? [/b]

about the test code:

1.the test code is simply enough to read,just 331 lines.

2.the error message "select timeout" is in function run(). 

3.I tried O_NONBLOCK mode when open the device node,or let tv.tv_sec=2,also get the same error.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>  
#include <fcntl.h>  
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <linux/fb.h>

#define CLEAR(x) memset (&(x), 0, sizeof (x))
 
struct buffer 
{
    void * start;
    size_t length;
};
 
#define PIX_FMT  V4L2_PIX_FMT_SRGGB10        //ov5693's fmt

static char * szDevName = "/dev/video0";     //node

static int iFd = -1;

static int iPicNum=60;              //will get 60 picture from camera
static int iFileCount=0;            //how many picture already gotten

static unsigned int iWidth=1920;    //pic's width
static unsigned int iHeight=1080;   //pic's height
static unsigned int iBuffersNum= 4;    //how many buffers will be use

struct buffer * buffers = NULL;     //array to store parameter of buffers

static int xioctl (int fd,int request,void * arg)       
{
    int r;
    do r = ioctl (fd, request, arg);
    while (-1 == r && EINTR == errno);
    return r;
}
 
static int read_frame (void)
{
    struct v4l2_buffer buf;
    unsigned int i;
 
    CLEAR (buf);
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
 
    if (-1 == xioctl (iFd, VIDIOC_DQBUF, &buf)) 
    {
        switch (errno) 
	    {
       	 	case EAGAIN:
//		                  printf( "\nEAGIN!!!\n " );
        			      return 0;
        	case EIO:    
        	default:
            		printf("\nVIDIOC_DQBUF\n");
                    exit(1);
        }
    }
 
    printf("\nI get a picture,show you this message!");

    if (-1 == xioctl (iFd, VIDIOC_QBUF, &buf))
    {
        printf("\nVIDIOC_QBUF\n");
        exit(1);
    }
 
    return 1;
}
 
static void run (void)
{
    unsigned int count;
    int frames;

    frames = iPicNum;
 
    while (frames-- > 0) 
    {
        for (;;) 
	    {
            fd_set fds;
            struct timeval tv;
            int r;
            FD_ZERO (&fds);
            FD_SET (iFd, &fds);

tv.tv_sec = 2;
            tv.tv_usec = 0;
 
            r = select (iFd + 1, &fds, NULL, NULL, &tv);
 
            if (-1 == r) 
	        {
                if (EINTR == errno)
                    continue;
                printf("\nselect\n");
                exit(1);
            }
 
            if (0 == r) 
	        {
                printf ("\nselect timeout\n");
                exit (1);
            }
 
            if (read_frame ())
                break;
         }
    }
}
 
static void stop_capturing (void)
{
    enum v4l2_buf_type type;
 
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (-1 == xioctl (iFd, VIDIOC_STREAMOFF, &type))
    {
        printf("\nVIDIOC_STREAMOFF\n");
        exit(1);
    }
}
 
static void start_capturing (void)
{
    unsigned int i;
    enum v4l2_buf_type type;
 
    for (i = 0; i < iBuffersNum; ++i) 
    {
        struct v4l2_buffer buf;
        CLEAR (buf);
 
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;
 
        if (-1 == xioctl (iFd, VIDIOC_QBUF, &buf))
        {
            printf("\nVIDIOC_QBUF error\n");
            exit(1);
        }
     }
 
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
    if (-1 == xioctl (iFd, VIDIOC_STREAMON, &type))
    {
        printf("\nVIDIOC_STREAMON failed\n");
        exit(1);
    }
}
 
static void uninit_device (void)
{
    unsigned int i;
 
    for (i = 0; i < iBuffersNum; ++i)
    {
            
        if (-1 == munmap (buffers[i].start, buffers[i].length))
        {
            printf("\nmunmap");
            exit(1);
        }
    }
    
    free (buffers);
}

static void init_mmap (void)
{
    int i=0;
    struct v4l2_requestbuffers req;

    CLEAR (req);
 
    req.count = iBuffersNum;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;
 
    if (-1 == xioctl (iFd, VIDIOC_REQBUFS, &req)) 
    {
        if (EINVAL == errno) 
	    {
            printf ("\n%s does not support memory mapping.\n", szDevName);
            exit (1);
        } 
        else 
	    {
            printf("\nVIDIOC_REQBUFS failed!\n");
            exit(1);
        }
    }
 
    if (req.count < iBuffersNum) 
    {   
        printf ("\nInsufficient buffer memory on %s\n",szDevName);
        exit (1);
    }
 
    buffers =(struct buffer *) calloc (req.count, sizeof (*buffers));
 
    if (!buffers) 
    {
        printf ("\nOut of memory\n");
        exit (1);
    }
 
    for (i = 0; i < req.count; ++i) 
    {
        struct v4l2_buffer buf;
 
        CLEAR (buf);
 
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;
 
        if (-1 == xioctl (iFd, VIDIOC_QUERYBUF, &buf))
        {
            printf("\nVIDIOC_QUERYBUF error\n");
            exit(1);
        }
 
        buffers[i].length = buf.length;
        buffers[i].start =mmap (NULL,buf.length,PROT_READ | PROT_WRITE ,MAP_SHARED,iFd, buf.m.offset);
 
//        printf( "\nlength=%d,start=0x%0x ",(int)(buffers[i].length),(unsigned int)(buffers[i].start) );

        if (MAP_FAILED == buffers[i].start)
        {
            printf("\nmmap error\n");
            exit(1);
        }
    }
}

static void init_device (void)
{
    struct v4l2_format fmt;
 
    CLEAR (fmt);
 
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = iWidth;  
    fmt.fmt.pix.height = iHeight;
    fmt.fmt.pix.pixelformat = PIX_FMT;
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
 
    if (-1 == xioctl (iFd, VIDIOC_S_FMT, &fmt))
    {
        printf("\nFailed to set fmt!");
        exit(1);
    }
 
    init_mmap ();
}
 
static void close_device (void)
{
    if (-1 == close (iFd))
    {
        printf("\nclose");
        exit(1);
    }
    iFd = -1;
}
 
static void open_device (void)
{
    struct stat st;  
 
    if (-1 == stat (szDevName, &st)) 
    {
        printf("\nCannot identify %s\n",szDevName);
        exit(1);
    }
 
    if (!S_ISCHR (st.st_mode)) 
    {
        printf("\n%s is not a device\n",szDevName);
        exit(1);
    }
 
    iFd = open (szDevName, O_RDWR | O_NONBLOCK, 0);
 
    if (-1 == iFd) 
    {
        printf("\nFailed to open %s",szDevName);
        exit(1);
    }
}
 
int main (int argc,char ** argv)
{
    open_device ();
 
    init_device ();
 
    start_capturing ();
 
    run ();
 
    stop_capturing ();
 
    uninit_device ();
 
    close_device ();
 
    exit (EXIT_SUCCESS);
 
return 0;
}

hello zuoye010,

could you please try below commands to access the camera sensor,
thanks

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=100

nvidia@tegra-ubuntu:~/work$ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=100
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 30.09 fps
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 30.04 fps
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 30.03 fps
<<<<<<<<

hello zuoye010,

please review your test application since default v4l2-ctl is able to access the sensor driver without failure,
thanks

It’s strangely.

It seems v4l2-ctl can get picture from the ov5693.

and I try my test code again,It can work!!!

I am confused now.but after all,I can get picture from camera,this what i wanted.

Thanks!

I modified my test code.

It seems nvidia’s video process unit need more time to catch the picture.

In some one’s code ,this is:
tv.tv_sec = 2;
tv.tv_usec = 0;

and I test it,use ov5693,at least is:
tv.tv_sec = 0;
tv.tv_usec = 500000;

means 500 millisecond.