Implementing IMX185 sensor mode for WUXGA resolution

We bought the IMX185 camera module and the camera adapter board from Leopard Imaging. The driver for the 1920x1080 resolution is working well using argus or gstreamer. For our application, we would need the full 1920x1200 resolution of the sensor, but unfortunately this resolution is not implemented in the driver. The guys from Leopard told me, that they currently can not implement the new sensor mode. Therefore I tried to adapt the driver on my own, but got stuck now. Maybe someone can give me a hint?

What I did so far:

  1. I added a new mode table in the imx185_mode_tbls.h. I hope, that I set the correct values from the sensor data sheet. Some settings in the table from Leopard are not clear for me, e.g. the cropping settings (WINWH). Nevertheless, I defined the following table:
    static imx185_reg imx185_1920x1200_crop_30fps[] = {
    	{0x3002, 0x01},
    	{0x3005, 0x01},
    	{0x3006, 0x00}, //MODE
    	{0x3007, 0x40}, //WINMODE
    	{0x3009, 0x01},
    	{0x300a, 0xf0},
    	//{0x300f, 0x01},
    	{0x3018, 0x28}, //VMAX LSB
    	{0x3019, 0x05}, //VMAX MSB
    	{0x301b, 0x53}, //HMAX LSB
    	{0x301c, 0x07}, //HMAX MSB
    	{0x301d, 0x08},
    	{0x301e, 0x02},
    	{0x3036, 0x10}, //VOB size designation
    	{0x3038, 0x00}, //WINPV LSB
    	{0x3039, 0x00}, //WINPV MSB
    	{0x303a, 0xB8}, //WINWV LSB
    	{0x303b, 0x04}, //WINWV MSB
    	{0x303c, 0x00}, //WINPH LSB
    	{0x303d, 0x00}, //WINPH MSB
    	{0x303e, 0x84}, //WINWH LSB
    	{0x303f, 0x07}, //WINWH MSB
    	{0x3048, 0x33},
    	{0x305C, 0x20}, //INCKSEL1
    	{0x305D, 0x00}, //INCKSEL2
    	{0x305E, 0x18}, //INCKSEL3
    	{0x305F, 0x00}, //INCKSEL4
    	{0x3063, 0x74}, //INCKSEL5
    	//{0x3084, 0x0f},
    	//{0x3086, 0x10},
    	//{0x30cf, 0xe1},
    	//{0x30d0, 0x29},
    	//{0x30d2, 0x9b},
    	//{0x30d3, 0x01},
    	{0x311d, 0x0a},
    	{0x3123, 0x0f},
    	{0x3126, 0xdf},
    	{0x3147, 0x87},
    	{0x31e0, 0x01},
    	{0x31e1, 0x9e},
    	{0x31e2, 0x01},
    	{0x31e5, 0x05},
    	{0x31e6, 0x05},
    	{0x31e7, 0x3a},
    	{0x31e8, 0x3a},
    	{0x3203, 0xc8},
    	{0x3207, 0x54},
    	{0x3213, 0x16},
    	{0x3215, 0xf6},
    	{0x321a, 0x14},
    	{0x321b, 0x51},
    	{0x3229, 0xe7},
    	{0x322a, 0xf0},
    	{0x322b, 0x10},
    	{0x3231, 0xe7},
    	{0x3232, 0xf0},
    	{0x3233, 0x10},
    	{0x323c, 0xe8},
    	{0x323d, 0x70},
    	{0x3243, 0x08},
    	{0x3244, 0xe1},
    	{0x3245, 0x10},
    	{0x3247, 0xe7},
    	{0x3248, 0x60},
    	{0x3249, 0x1e},
    	{0x324b, 0x00},
    	{0x324c, 0x41},
    	{0x3250, 0x30},
    	{0x3251, 0x0a},
    	{0x3252, 0xff},
    	{0x3253, 0xff},
    	{0x3254, 0xff},
    	{0x3255, 0x02},
    	{0x3257, 0xf0},
    	{0x325a, 0xa6},
    	{0x325d, 0x14},
    	{0x325e, 0x51},
    	{0x3260, 0x00},
    	{0x3261, 0x61},
    	{0x3266, 0x30},
    	{0x3267, 0x05},
    	{0x3275, 0xe7},
    	{0x3281, 0xea},
    	{0x3282, 0x70},
    	{0x3285, 0xff},
    	{0x328a, 0xf0},
    	{0x328d, 0xb6},
    	{0x328e, 0x40},
    	{0x3290, 0x42},
    	{0x3291, 0x51},
    	{0x3292, 0x1e},
    	{0x3294, 0xc4},
    	{0x3295, 0x20},
    	{0x3297, 0x50},
    	{0x3298, 0x31},
    	{0x3299, 0x1f},
    	{0x329b, 0xc0},
    	{0x329c, 0x60},
    	{0x329e, 0x4c},
    	{0x329f, 0x71},
    	{0x32a0, 0x1f},
    	{0x32a2, 0xb6},
    	{0x32a3, 0xc0},
    	{0x32a4, 0x0b},
    	{0x32a9, 0x24},
    	{0x32aa, 0x41},
    	{0x32b0, 0x25},
    	{0x32b1, 0x51},
    	{0x32b7, 0x1c},
    	{0x32b8, 0xc1},
    	{0x32b9, 0x12},
    	{0x32be, 0x1d},
    	{0x32bf, 0xd1},
    	{0x32c0, 0x12},
    	{0x32c2, 0xa8},
    	{0x32c3, 0xc0},
    	{0x32c4, 0x0a},
    	{0x32c5, 0x1e},
    	{0x32c6, 0x21},
    	{0x32c9, 0xb0},
    	{0x32ca, 0x40},
    	{0x32cc, 0x26},
    	{0x32cd, 0xa1},
    	{0x32d0, 0xb6},
    	{0x32d1, 0xc0},
    	{0x32d2, 0x0b},
    	{0x32d4, 0xe2},
    	{0x32d5, 0x40},
    	{0x32d8, 0x4e},
    	{0x32d9, 0xa1},
    	{0x32ec, 0xf0},
    	{0x3303, 0x00}, //REPETITION
    	{0x3305, 0x03}, //PHYSICAL_Lane_NUM
    	{0x3314, 0x0E}, //OB_SIZE_V
    	{0x3315, 0x01}, //NULL0_SIZE_V
    	{0x3316, 0x04}, //NULL1_SIZE_V
    	{0x3317, 0x04}, //NULL2_SIZE_V
    	{0x3318, 0xB0}, //PIC_SIZE_V LSB
    	{0x3319, 0x04}, //PIC_SIZE_V MSB
    	{0x332c, 0x40}, //THSEXIT
    	{0x332d, 0x20}, //TCLKPRE
    	{0x332e, 0x03}, //TLPXESC
    	{0x333e, 0x0c}, //CSI_DT_FMT [7:0]
    	{0x333f, 0x0c}, //CSI_DT_FMT [15:8]
    	{0x3340, 0x03}, //CSI_Lane_MODE
    	{0x3341, 0x20}, //INCK_FREQ [7:0]
    	{0x3342, 0x25}, //INCK_FREQ [15:8]
    	{0x3343, 0x68}, //TCLK_POST
    	{0x3344, 0x20}, //THS_PREPARE
    	{0x3345, 0x40}, //THS_ZERO_MIN
    	{0x3346, 0x28}, //THS_TRAIL
    	{0x3347, 0x20}, //TCLK_TRAIL_MIN
    	{0x3348, 0x18}, //TCLK_PREPARE
    	{0x3349, 0x78}, //TCLK_ZERO
    	{0x334a, 0x28}, //TLPX
    	{0x334e, 0xB4}, //INCK_FREQ2 [7:0]
    	{0x334f, 0x01}, //INCK_FREQ2 [10:8]
    	{0x3020, 0xe1},
    	{0x3021, 0x04},
    	{IMX185_TABLE_END, 0x00}
  2. I changed some defines (IMX185_DEFAULT_MODE, IMX185_DEFAULT_WIDTH, IMX185_DEFAULT_HEIGHT) in the imx185.c
  3. I adapted the modes in the device tree file (tegra210-camera-li-mipi-adpt-a00.dsi). Here I am also not sure if I set all values correctly.
    mode0 {/*mode IMX185_MODE_1920X1200_CROP_30FPS*/
    	mclk_khz = "37125";
    	num_lanes = "4";
    	tegra_sinterface = "serial_a";
    	discontinuous_clk = "no";
    	dpcm_enable = "false";
    	cil_settletime = "0";
    	dynamic_pixel_bit_depth = "12";
    	csi_pixel_bit_depth = "12";
    	mode_type = "bayer";
    	pixel_phase = "rggb";
    	active_w = "1920";
    	active_h = "1200";
    	readout_orientation = "0";
    	line_length = "3750";
    	inherent_gain = "1";
    	mclk_multiplier = "4";
    	pix_clk_hz = "148500000";
    	min_gain_val = "0"; /* dB */
    	max_gain_val = "48"; /* dB */
    	min_hdr_ratio = "1";
    	max_hdr_ratio = "1";
    	min_framerate = "1.5";
    	max_framerate = "30";
    	min_exp_time = "30";
    	max_exp_time = "680000";
    	embedded_metadata_height = "0";

Unfortunately, the new sensor mode does not work. I only get timeouts using argus or gstreamer:

Thread 1 getting next capture

Thread 1 is waiting

Thread 3 is waiting

FiberScheduler: cc 2101, fiber 0x7f100008c0 aborted in async operation

CaptureService cancelling request 10512

FiberScheduler: cc 2102, fiber 0x7f10000d00 aborted in async operation

Waiting 100ms for late buffer unlock during abort.

SCF: Error Timeout:  (propagating from src/services/capture/CaptureServiceEvent.cpp, function wait(), line 59)
Error: Camera HwEvents wait, this may indicate a hardware timeout occured,abort current/incoming cc
Created fiber 0x7f10001140 for CC 2104

Thread 4 is working on CC 2104

Fiber 0x7f10001140 is aborting in CC 3

FiberScheduler: cc 2104, fiber 0x7f10001140 aborted


Error: waitCsiFrameStart timeout guid 0
launchCC abort cc 2105

Created fiber 0x7f7a446b30 for CC 2105

SCF: Error Timeout:  (propagating from src/api/Session.cpp, function capture(), line 731)
FiberScheduler: fiber 0x7f10001140 exiting

The problem is, that I do not know, what the reason for this timeout is. Can anybody give me a hint, what could be wrong or what is the best way to debug the driver?

I did not check on the mode register setting sensor side, but from Tegra VI side,

    mclk_multiplier = "4";
pix_clk_hz = "148500000";

It seems that you double the pixel clock. Do you need to run that high of freq knowing your target frame rate remains and only adding 120 pixels vertical resolution? Could you lower your pixel clock? Let’s try to have reasonable setting so you can get the frame data from camera first.

That means by lowering pixel clock should at least allow you to see frame data coming from sensor even though the image might not look good but that can be adjusted after your program is running normally.

Thanks for the reply! Today I could solve the issue. As Leopard did, I also used the window cropping mode of the sensor. According to the datasheet, the parameter WINWH (horizontal cropping size designation) must be a multiple of 8 plus 4. Because I wanted to have 1920 horizontal pixels, I set the value to 1924. Unfortunately this did not work. So I looked again at the register settings from Leopard and could see, that they have set this parameter to 1916. I don’t know why, but after setting this value to 1916, the sensor is working. Do you know what the meaning of the parameter is and why Leopard set this to 1916?

Btw.: I also tried to reduce the pix_clk_hz, as you suggest. With this settings, I only get the half image. With pix_clk_hz=148500000 the full image is visible.