hi everyone,
I develop our sensor base on the driver of imx219. my sensor is mipi one lane output 1616x1216 20ftp raw image.
here is my mode in dtsi, I just defined one mode about 1616x1216.
mode0 {
mclk_khz = "24000";
num_lanes = "1";
tegra_sinterface = "serial_a";
phy_mode = "DPHY";
discontinuous_clk = "no";
dpcm_enable = "false";
cil_settletime = "0";
active_w = "1616";
active_h = "1216";
pixel_t = "bayer_rggb";
readout_orientation = "0";
line_length = "1960";
inherent_gain = "1";
mclk_multiplier = "3.33";
pix_clk_hz = "72000000";
gain_factor = "16";
framerate_factor = "1000000";
exposure_factor = "1000000";
min_gain_val = "16"; /* 1.00x */
max_gain_val = "170"; /* 10.66x */
step_gain_val = "1";
default_gain = "16"; /* 1.00x */
min_hdr_ratio = "1";
max_hdr_ratio = "1";
min_framerate = "2000000"; /* 2.0 fps */
max_framerate = "21000000"; /* 21.0 fps */
step_framerate = "1";
default_framerate = "20000000"; /* 20.0 fps */
min_exp_time = "13"; /* us */
max_exp_time = "683709"; /* us */
step_exp_time = "1";
default_exp_time = "2495"; /* us */
embedded_metadata_height = "0";
};
I use below code to test the driver
static int fd_cam=-1 ;
static struct v4l2_requestbuffers reqbuf;
static VideoBuffer framebuf[BUFFER_COUNT];
static struct v4l2_buffer buf;
int Camera_OpenCam()
{
// open device
fd_cam = open(CAMERA_DEVICE, O_RDWR, 0);
if (fd_cam < 0) {
printf("Open %s failed\n", CAMERA_DEVICE);
return -1;
}
return fd_cam ;
}
int Camera_CloseCam()
{
return close(fd_cam);
}
int Camera_GetCamInfo()
{
int ret=-1 ;
// GetDevicInfo
struct v4l2_capability cap;
ret = ioctl(fd_cam, VIDIOC_QUERYCAP, &cap);
if (ret < 0) {
printf("VIDIOC_QUERYCAP failed (%d)\n", ret);
return ret;
}
// Print capability infomations
printf("Capability Informations:\n");
printf(" driver: %s\n", cap.driver);
printf(" card: %s\n", cap.card);
printf(" bus_info: %s\n", cap.bus_info);
printf(" version: %08X\n", cap.version);
printf(" capabilities: %08X\n", cap.capabilities);
return ret ;
}
int Camera_SetCamFMT()
{
int ret = -1 ;
// SetCamFMT
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = VIDEO_WIDTH;
fmt.fmt.pix.height = VIDEO_HEIGHT;
fmt.fmt.pix.pixelformat = VIDEO_FORMAT;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
ret = ioctl(fd_cam, VIDIOC_S_FMT, &fmt);
if (ret < 0) {
printf("VIDIOC_S_FMT failed (%d)\n", ret);
return ret;
}
// GetCamFMT to Verify
ret = ioctl(fd_cam, VIDIOC_G_FMT, &fmt);
if (ret < 0) {
printf("VIDIOC_G_FMT failed (%d)\n", ret);
return ret;
}
// Print Stream Format
printf("Stream Format Informations:\n");
printf(" type: %d\n", fmt.type);
printf(" width: %d\n", fmt.fmt.pix.width);
printf(" height: %d\n", fmt.fmt.pix.height);
char fmtstr[8];
memset(fmtstr, 0, 8);
memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
printf(" pixelformat: %s\n", fmtstr);
printf(" field: %d\n", fmt.fmt.pix.field);
printf(" bytesperline: %d\n", fmt.fmt.pix.bytesperline);
printf(" sizeimage: %d\n", fmt.fmt.pix.sizeimage);
printf(" colorspace: %d\n", fmt.fmt.pix.colorspace);
printf(" priv: %d\n", fmt.fmt.pix.priv);
printf(" raw_date: %s\n", fmt.fmt.raw_data);
return 0 ;
}
int Camera_RequestBuffers(struct v4l2_requestbuffers *reqbuf__)
{
// Request Buffers from kernel
int ret =-1 ;
reqbuf__->count = BUFFER_COUNT;
reqbuf__->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf__->memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd_cam , VIDIOC_REQBUFS, reqbuf__);
if(ret < 0) {
printf("VIDIOC_REQBUFS failed (%d)\n", ret);
return ret;
}
return ret ;
}
int Camera_MapAndEnqueue(struct v4l2_requestbuffers *reqbuf__, struct v4l2_buffer *buf__,VideoBuffer *framebuf_)
{
int i=-1,ret=-1 ;
// Map And Enqueue
for (i = 0; i < reqbuf__->count; i++)
{
buf__->index = i;
buf__->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf__->memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd_cam , VIDIOC_QUERYBUF, buf__);
if(ret < 0) {
printf("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
return ret;
}
// mmap buffer
framebuf_[i].length = buf__->length;
framebuf_[i].start = (char *) mmap(0, buf__->length, PROT_READ|PROT_WRITE, MAP_SHARED, fd_cam, buf__->m.offset);
if (framebuf_[i].start == MAP_FAILED) {
printf("mmap (%d) failed: %s\n", i, strerror(errno));
return -1;
}
// Queen buffer
ret = ioctl(fd_cam , VIDIOC_QBUF, buf__);
if (ret < 0) {
printf("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
return -1;
}
printf("Frame buffer %d: address=0x%x, length=%d\n", i, (unsigned int)framebuf_[i].start, framebuf_[i].length);
}
return 0 ;
}
void Camera_UNMap(VideoBuffer *framebuf_)
{
int i=-1 ;
// Release the resource
for (i=0; i< 4; i++)
{
munmap(framebuf_[i].start, framebuf_[i].length);
}
}
int Camera_StartCameraStreaming()
{
int ret=-1 ;
// start camera streaming
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd_cam, VIDIOC_STREAMON, &type);
if (ret < 0) {
printf("VIDIOC_STREAMON failed (%d)\n", ret);
return ret;
}
return ret ;
}
int Camera_DeQueueBufferGetFrame( struct v4l2_buffer *buf_)
{
int ret=-1 ;
// De-queue buffer ,Get frame
ret = ioctl(fd_cam, VIDIOC_DQBUF, buf_);
if (ret < 0) {
printf("VIDIOC_DQBUF failed (%d)\n", ret);
return ret;
}
return ret ;
}
int Camera_EnQueueBuffer(struct v4l2_buffer *buf_)
{
int ret = -1 ;
// Re-queen buffer
ret = ioctl(fd_cam, VIDIOC_QBUF, buf_);
if (ret < 0) {
printf("VIDIOC_QBUF failed (%d)\n", ret);
return ret;
}
return 0 ;
}
void Camera_RecordYUYV(const char* YUYVFILE ,struct v4l2_buffer *buf_)
{
// record frame YUYV
FILE *fp = fopen(YUYVFILE, "wb");
if (fp < 0) {
printf("open frame data file failed\n");
return ;
}
fwrite(framebuf[buf_->index].start, 1, buf_->length, fp);
fclose(fp);
printf("Capture one frame saved in %s\n", YUYVFILE);
}
int main()
{
Camera_OpenCam();
Camera_GetCamInfo() ;
Camera_SetCamFMT();
Camera_RequestBuffers(&reqbuf);
Camera_MapAndEnqueue(&reqbuf,&buf,framebuf);
Camera_StartCameraStreaming();
Camera_DeQueueBufferGetFrame(&buf);
Camera_RecordYUYV(CAPTURE_FILE,&buf);
Camera_EnQueueBuffer(&buf);
Camera_UNMap(framebuf);
Camera_CloseCam();
printf("Camera test Done.\n");
return 0;
}
and the output in console
Capability Informations:
driver: tegra-video
card: vi-output, imx219-zx 6-003d
bus_info: platform:54080000.vi:0
version: 0004098C
capabilities: 84200001
Stream Format Informations:
type: 1
width: 1616
height: 1216
pixelformat: RG10
field: 1
bytesperline: 3232
sizeimage: 3930112
colorspace: 8
priv: -17970434
raw_date: P
Frame buffer 0: address=0x7fb21000, length=3930112
Frame buffer 1: address=0x7f761000, length=3930112
Frame buffer 2: address=0x7f3a1000, length=3930112
Frame buffer 3: address=0x7efe1000, length=3930112
the test code didn’t return when doing VIDIOC_DQBUF. and some error log in kern.log
Aug 14 16:29:46 leon-desktop kernel: [ 1322.733104] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 0
Aug 14 16:29:46 leon-desktop kernel: [ 1322.813535] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 1
Aug 14 16:29:46 leon-desktop kernel: [ 1322.894176] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 2
Aug 14 16:29:46 leon-desktop kernel: [ 1322.974110] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 3
Aug 14 16:29:46 leon-desktop kernel: [ 1323.054202] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 4
Aug 14 16:29:46 leon-desktop kernel: [ 1323.134132] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 5
Aug 14 16:29:46 leon-desktop kernel: [ 1323.213660] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 6
Aug 14 16:29:46 leon-desktop kernel: [ 1323.293264] vi 54080000.vi: tegra_channel_error_status:error 4000 frame 7
......
the error code point to csi error about TEGRA_CSI_PIXEL_PARSER_STATUS, but I don’t know it’s actually meaning, and how to fix it?
by the way, when I use nvgstcapture it’s preview successfully!!