跳转至

Sensor移植指南

REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 07/16/2024

    1. 环境准备

    开始Porting之前,请先确保Sensor的接线没有问题,MIPI Sensor接线可以参考这篇文档 SENSOR 使用参考,在不同CHIP上基本的原理也相同

    首先需要确认需求,包含Sensor的分辨率,帧率,像素位宽,MIPI Lane数量,mclk 频率,将需求给到厂商,并让其提供数据手册与初始化表。

    2. Sensor驱动程序移植的文件名规范

    为了规范所有Sgs Sensor Driver 名称的命名,我们制定了Sgs Sensor Driver 移植规范,在移植Sensor driver时请遵循以下说明。

    2.1. Sensor驱动名称规范

    drv_ss_<Sensor Type>_<Sensor interface>_<others>.c
    
    参数 说明
    Sensor Type Sensor命名,例如 imx307、imx415。建议使用小写。
    Sensor interface Sensor接口类型,例如:mipi、lvds,但parallel可以忽略不填写。建议使用小写。
    others 如无其他补充,可忽略。建议使用小写。

    3. Sensor移植相关硬件知识

    本文档介绍了如何移植Sgs Sensor驱动,包括硬件基础知识、Sgs的软件控制Sensor API(sensor handle)、Sensor接口API(Sensor-IF)以及软件移植流程。本文档以imx415的Sensor驱动为例,您可以按照本文档中的说明逐步完成Sensor移植。

    首先我们介绍一下硬件的相关知识以及相应的源代码,以便于大家更容易的理解。

    3.1. Sensor电源顺序

    检查Sensor数据表中的通电顺序规范。请遵循以下电源顺序 1.1V > 1.8V > 2.9V,这是 imx415 Sensor数据表的要求。

    图 1:IMX415 Sensor电源顺序规范

    表1:IMX415 Sensor电源序列时序表

    3.1.1 对应源代码

    可以通过Sensor驱动句柄初始化函数中的“handle->pCus_sensor_poweron”来控制Sensor上电和复位引脚,如果需要修改Sensor上电时序,请检查Sensor特性和硬件设计。

    static int pCus_poweron(ms_cus_sensor *handle, u32 idx)  {
        ISensorIfAPI *sensor_if = &handle->sensor_if_api;
        //Sensor上电顺序
        sensor_if->PowerOff(idx, handle->pwdn_POLARITY); //Powerdn 拉低
        sensor_if->Reset(idx, handle->reset_POLARITY); // Rst 拉低
        sensor_if->SetIOPad(idx, handle->sif_bus, handle->interface_attr.attr_mipi.mipi_lane_num);
        sensor_if->SetCSI_Clk(idx, CUS_CSI_CLK_216M);
        sensor_if->SetCSI_Lane(idx, handle->interface_attr.attr_mipi.mipi_lane_num, ENABLE);
        sensor_if->SetCSI_LongPacketType(idx, 0, 0x1C00, 0);
        if (handle->interface_attr.attr_mipi.mipi_hdr_mode == CUS_HDR_MODE_SONY_DOL)
            sensor_if->SetCSI_hdr_mode(idx, handle->interface_attr.attr_mipi.mipi_hdr_mode, 1);
    
        sensor_if->PowerOff(idx, !handle->pwdn_POLARITY);
        //Sensor板 PWDN 启用,1.8V 和 2.9V 需要 30ms 后拉高
        SENSOR_MSLEEP(31);
        sensor_if->Reset(idx, !handle->reset_POLARITY);
        SENSOR_UDELAY(1);
        sensor_if->MCLK(idx, 1, handle->mclk);
        SENSOR_DMSG("Sensor Power On finished\n");
        return SUCCESS;
    }
    

    注意:

    以下是 Sgs Sensor板电源电路原理图。上电后,1.1V、1.8V、2.9V 电源将被拉高。首先是 1.1V,然后是 1.8V 和 2.9V,您可以使用示波器在Sensor板上测量它。

    图 2:IMX415 Sensor电源电路

    3.2. Sensor I2C 从机地址检查

    Sgs SoC 需要通过 I2C 与Sensor通信,请先检查Sensor I2C 从机地址。

    表 2:IMX415 Sensor从机 ID 表

    注意:

    检查 I2C 从机模式选项的Sensor板原理图。

    图 3:IMX415 Sensor板 I2C 从机模式

    3.2.1 对应源代码

    Sensor驱动I2C设置中宏定义

    ////////////////////////////////////
    // I2C Info                         //
    ////////////////////////////////////
    #define SENSOR_I2C_ADDR     0x34        //I2C slave address
    #define SENSOR_I2C_SPEED    300000      //I2C speed, 60000~320000
    #define SENSOR_I2C_LEGACY  I2C_NORMAL_MODE
    #define SENSOR_I2C_FMT     I2C_FMT_A16D8 //CUS_I2C_FMT_A8D8,
                                                CUS_I2C_FMT_A8D16,
                                                CUS_I2C_FMT_A16D8,
                                                CUS_I2C_FMT_A16D16
    

    注意: I2C 控制接口的Sensor IF 位于handle初始函数中

    handle->i2c_cfg.mode     = SENSOR_I2C_LEGACY;    //(CUS_ISP_I2C_MODE) FALSE;
    handle->i2c_cfg.fmt      = SENSOR_I2C_FMT;       //CUS_I2C_FMT_A16D8;
    handle->i2c_cfg.address  = SENSOR_I2C_ADDR;      //0x34;
    handle->i2c_cfg.speed    = SENSOR_I2C_SPEED;     //未实现,请配置dts或 sysdesc
    

    3.3. Sensor MCLK 支持

    每个Sensor可以支持不同的MCLK,我们可以提供的MCLK列表如下,您可以从Sensor供应商提供的初始化设置中找到Sensor对应的MCLK,宏定义中的Sensor MCLK设置

    ////////////////////////////////////
    // MCLK Info                        //
    ////////////////////////////////////
    /******* Support MCLK List *******
    *    CUS_CMU_CLK_27MHZ   / CUS_CMU_CLK_21P6MHZ  / CUS_CMU_CLK_12MHZ,
    *    CUS_CMU_CLK_5P4MHZ  / CUS_CMU_CLK_36MHZ    / CUS_CMU_CLK_54MHZ,
    *    CUS_CMU_CLK_43P2MHZ / CUS_CMU_CLK_61P7MHZ  / CUS_CMU_CLK_72MHZ,
    *    CUS_CMU_CLK_48MHZ    / CUS_CMU_CLK_24MHZ    / CUS_CMU_CLK_37P125MHZ,
    ******End of Support MCLK List*******/
    #define Preview_MCLK_SPEED           CUS_CMU_CLK_27MHZ
    

    3.3.1 对应源代码

    在handle初始函数中的Sensor MCLK 控制接口:

    ////////////////////////////////////
    //   set mclk                        //
    //   please check pCus_poweron     //
    ////////////////////////////////////
    sensor_if->MCLK(idx ,  ENABLE, UseParaMclk(SENSOR_DRV_PARAM_MCLK()));
    

    4. Sensor移植相关软件控制

    在介绍了硬件相关知识和相应的源代码之后,这部分我们将介绍Sgs的软件控制API(Sensor handle)和Sensor接口API(Sensor-IF)。

    4.1. Sensor驱动支持模式定义

    Sgs Sensor驱动可以提供多种注册Sensor支持的行为模式,下面我们将针对这些注册Sensor支持的行为模式进行讲解,您可以在路径中查看更多宏定义的详细信息:

    driver/SensorDriver/drv/inc/drv_sensor_common.h

    4.1.1 pure linear、parallel sensor和2-frame HDR的宏定义

    #define SENSOR_DRV_ENTRY_IMPL_END_EX (Name, LinearEntry, HdrSefEntry,
                                            HdrLefEntry, PrivateDataType)
    

    表 3:Sensor驱动程序“SENSOR_DRV_ENTRY_IMPL_END_EX”定义

    参数 描述
    Name Sensor名称及支持模式
    LinearEntry Sensor线性模式handle初始函数
    HdrSefEntry Sensor HDR 短曝光handle初始函数
    HdrLefEntry Sensor HDR 长曝光handle初始函数
    PrivateDataType Sensor私有数据类型

    4.1.2 3-frame HDR的宏定义

    #define SENSOR_DRV_ENTRY_IMPL_END_EX2 (Name, LinearEntry, HdrSefEntry,
                                            HdrLefEntry, HdrMefEntry,
                          PrivateDataType)
    

    表4:Sensor驱动程序“SENSOR_DRV_ENTRY_IMPL_END_EX2”定义

    参数 描述
    Name Sensor名称及支持模式
    LinearEntry Sensor线性模式handle初始函数
    HdrSefEntry Sensor HDR 短曝光handle初始函数
    HdrLefEntry Sensor HDR 长曝光handle初始函数
    HdrMefEntry Sensor HDR 中曝光handle初始函数
    PrivateDataType Sensor私有数据类型

    例如IMX415 sensor支持线性及2-frame HDR模式,可参考IMX415 sensor驱动,将其填入“SENSOR_DRV_ENTRY_IMPL_END_EX”定义中。

    SENSOR_DRV_ENTRY_IMPL_END_EX(  IMX415_HDR,
                                cus_camsensor_init_handle,
                                cus_camsensor_init_handle_hdr_dol_sef,
                                cus_camsensor_init_handle_hdr_dol_lef,
                                imx415_params
                                );
    

    4.2. Sensor驱动handle函数介绍

    接下来我们在 linear 和 HDR handle初始函数中对 handle API 进行介绍和讲解,我们可以通过 handle API 来控制、设置或者读取 sensor 的任意状态,这里以 imx415 的 sensor 驱动为例,大家可以按照本文档中的说明,逐步完成 linear 和 HDR 模式的 sensor 移植。

    4.2.1 Sensor型号ID API的handle

    设置Sensor名称和模式信息

    表 5:handle的型号名称API列表

    参数 描述 注意
    handle ->strSensorStreamName 为 libcamera 用户注册设置Sensor模型 MIPI: IMX415_MIPI
    PARALLEL: IMX323_PARL
    HDR: IMX415_MIPI_HDR_SEF, IMX415_MIPI_HDR_LEF

    4.2.2 I2C的handle

    设置 I2C 硬件以进行配置

    表 6:handle的I2C配置列表

    参数 描述 注意
    handle->i2c_cfg.mode 注册 I2C 模式 I2C_NORMAL_MODE
    /Sensor驱动程序只能使用 I2C_NORMAL_MODE/
    I2C_LEGACY_MODE
    /请勿使用/
    handle->i2c_cfg.fmt 注册设置 I2C 地址位和数据长度的格式。 I2C_FMT_A8D8,
    I2C_FMT_A16D8,
    I2C_FMT_A8D16,
    I2C_FMT_A16D16,
    I2C_FMT_END
    /保留/
    /Ex I2C_FMT_A16D8 表示 16 位地址、8 位数据/
    handle->i2c_cfg.address 注册设置Sensor I2C 从机地址,Sgs SoC 支持 8 位从机地址 从Sensor数据表检查
    handle->i2c_cfg.speed 注册设置Sensor最大 I2C 速度(未使用) 通过 dts 或 sysdesc 进行 I2C 速度配置

    4.2.3 Sensor解析能力处理

    设置Sensor支持并实现输出图像信息。

    表 7:Sensor解析能力列表的handle

    参数 描述 注意
    handle->video_res_supported.num_res 注册设置Sensor支持分辨率
    handle->video_res_supported.ulcur_res 注册设置Sensor当前分辨率 默认值:0
    handle->video_res_supported.res[n].u16width 注册设置Sensor支持宽度
    handle->video_res_supported.res[n].u16height 注册设置Sensor支持高度
    handle->video_res_supported.res[n].u16max_fps 注册设置Sensor支持预览最大fps
    handle->video_res_supported.res[n].u16min_fps 注册设置Sensor支持预览最低fps
    handle->video_res_supported.res[n].u16crop_start_x 注册设置 VIF 裁剪Sensor输出图像 X 的起点
    handle->video_res_supported.res[n].u16crop_start_y 注册设置 VIF 裁剪Sensor输出图像 Y 的起点
    handle->video_res_supported.res[n].u16OutputWidth 注册设置VIF输出有效像素
    handle->video_res_supported.res[n].u16OutputHeight 注册设置 VIF 输出有效线
    handle->video_res_supported.res[n].strResDesc 注册设置Sensor分辨率和fps字符串 CamOsStrncpy(handle->video_res_supported.res[i].strResDesc, “1920x1080@30fps”, CamOsStrlen(1920x1080@30fps));
    handle->video_res_supported.res[n].u16MinFrameLengthLine 注册获取Sensor每行的最小帧长度
    handle->video_res_supported.res[n].u16RowTime 注册获取Sensor每行的时间
    handle->video_res_supported.res[n].u16PixelSize 注册获取线的Sensor像素大小

    4.2.4 Sensor信息处理

    设置Sensor信息以进行配置

    表 8:Sensor信息接口注册列表的handle

    参数 描述 注意
    handle->sif_bus 注册设置Sensor接口总线类型 SENSOR_IFBUS_TYPE
    CUS_SENIF_BUS_PARL = 0,
    /Sensor数据总线为 parallel/
    CUS_SENIF_BUS_MIPI = 1,
    /*Sensor数据总线为 mipi */
    CUS_SENIF_BUS_BT601 = 2,
    CUS_SENIF_BUS_BT656 = 3,
    CUS_SENIF_BUS_BT1120 = 4,
    handle->data_prec 注册设置Sensor输出原始数据精度 SENSOR_DATAPREC
    CUS_DATAPRECISION_8 = 0,
    /原始数据精度8位/
    CUS_DATAPRECISION_10 = 1,
    /原始数据精度10位/
    CUS_DATAPRECISION_16 = 2,
    /原始数据精度16位/
    CUS_DATAPRECISION_12 = 3,
    /原始数据精度12位/
    CUS_DATAPRECISION_14 = 4,
    /原始数据精度14位/
    handle->bayer_id 注册设置Sensor bayer起始id SENSOR_BAYERID
    CUS_BAYER_RG = 0、
    CUS_BAYER_GR、
    CUS_BAYER_BG、
    CUS_BAYER_GB、
    handle->RGBIR_id 注册设置Sensor RGB-IR起始id

    如果 不是 RGB-IR Sensor,请设置*CUS_RGBIR_NONE*
    SENSOR_RGBIRID
    CUS_RGBIR_NONE = 0,
    CUS_RGBIR_R0 = 1,
    CUS_RGBIR_G0 = 2,
    CUS_RGBIR_B0 = 3,
    CUS_RGBIR_G1 = 4,
    CUS_RGBIR_G2 = 5,
    CUS_RGBIR_I0 = 6,
    CUS_RGBIR_G3 = 7,
    CUS_RGBIR_I1 = 8
    handle->snr_pad_mode 注册Sensor主从模式 CUS_SENSOR_MASTER_MODE = 0,
    CUS_SENSOR_SLAVE_MODE = 1,

    4.2.5 mipi 信息handle

    设置 mipi 以进行配置

    表9:mipi Sensor接口注册列表的handle

    参数 描述 注意
    handle->interface_attr.attr_mipi.mipi_lane_num 注册设置 MIPI 通道数 默认值:4
    handle->interface_attr.attr_mipi.mipi_data_format 注册设置MIPI数据格式 CUS_SEN_INPUT_FORMAT_YUV422,
    CUS_SEN_INPUT_FORMAT_RGB,
    handle->interface_attr.attr_mipi.mipi_yuv_order 注册设置MIPI yuv 顺序 仅适用于 yuv Sensor
    handle->interface_attr.attr_mipi.mipi_hdr_mode 注册设置MIPI HDR 模式 CUS_HDR_MODE_NONE
    /无 HDR/
    CUS_HDR_MODE_SONY_DOL
    /索尼标准线信息输出/
    CUS_HDR_MODE_DCG
    /双增益 HDR/
    CUS_HDR_MODE_EMBEEDED_RAW8
    /嵌入式 8bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW10
    /嵌入式 10bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW12
    /嵌入式 12bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW14
    /嵌入式 14bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW16
    /嵌入式 16bit HDR/
    CUS_HDR_MODE_COMP
    /压缩 HDR/
    CUS_HDR_MODE_LI
    /行交错 HDR/
    CUS_HDR_MODE_COMP_VS
    /压缩 HDR + very short/
    CUS_HDR_MODE_VC
    /虚拟通道模式/
    CUS_HDR_MODE_MAX
    注意:
    在旧版的CUS_HDR_MODE_DCG 代表通过虚拟通道传输的HDR,在新版的架构下更名为CUS_HDR_MODE_VC。
    handle->interface_attr.attr_mipi.mipi_hdr_virtual_channel_num 注册设置HDR虚拟通道数根据各个sensor VC模式头文件定义 例如imx415:
    长曝光帧数: 0
    短曝光帧数: 1
    handle->interface_attr.attr_mipi.mipi_hdr_fusion_type 注册设置 HDR 融合类型 CUS_HDR_FUSION_TYPE_NONE,(默认)
    CUS_HDR_FUSION_TYPE_2T1,
    CUS_HDR_FUSION_TYPE_3T1,

    4.2.6 Parallel信息handle

    设置Parallel以进行配置

    表 10:Parallel Sensor接口注册列表的handle

    参数 描述 注意
    handle->interface_attr.attr_parallel.paral_data_format 注册设置parallel sensor数据格式 CUS_SEN_INPUT_FORMAT_YUV422,
    CUS_SEN_INPUT_FORMAT_RGB,
    handle->interface_attr.attr_parallel. paral_yuv_order 注册设置parallel sensor yuv 顺序 仅适用于 yuv sensor

    4.2.7 lvds 信息handle

    设置 lvds 以进行配置

    表11:lvds Sensor接口注册列表的handle

    参数 描述 注意
    handle->interface_attr.attr_lvds.lvds_lane_num 注册设置 LVDS 通道数 默认值:4
    handle->interface_attr.attr_lvds.lvds_data_format 注册设置 LVDS 数据格式 CUS_SEN_INPUT_FORMAT_YUV422,
    CUS_SEN_INPUT_FORMAT_RGB,
    handle->interface_attr.attr_lvds.lvds_yuv_order 注册设置 LVDS yuv 顺序 仅适用于 yuv Sensor
    handle->interface_attr.attr_lvds.lvds_hsync_mode 注册设置 HDR 虚拟通道 0 水平同步模式 SENSOR_MIPI_HSYNC_MODE
    PACKET_HEADER_EDGE1 = 0,
    /数据包头边缘/
    PACKET_HEADER_EDGE2 = 1,
    /行结束边缘/
    PACKET_HEADER_EDGE3 = 2,
    /行起始边缘/
    PACKET_FOOTER_EDGE = 3,
    /数据包尾部边缘/
    handle->interface_attr.attr_lvds.lvds_sampling_delay 注册设置LVDS开始采样延迟 BIT[7:0]: clk_skip_ns
    BIT[15:8]: data_skip_ns
    handle->interface_attr.attr_ lvds.lvds_hdr_mode 注册设置 LVDS HDR 模式 CUS_HDR_MODE_NONE
    /无 HDR/
    CUS_HDR_MODE_SONY_DOL
    /索尼标准线信息输出/
    CUS_HDR_MODE_DCG
    /双增益 HDR/
    CUS_HDR_MODE_EMBEEDED_RAW8
    /嵌入式 8bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW10
    /嵌入式 10bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW12
    /嵌入式 12bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW14
    /嵌入式 14bit HDR/
    CUS_HDR_MODE_EMBEEDED_RAW16
    /嵌入式 16bit HDR/
    CUS_HDR_MODE_COMP
    /压缩 HDR/
    CUS_HDR_MODE_LI
    /行交错 HDR/
    CUS_HDR_MODE_COMP_VS
    /压缩 HDR + very short/
    CUS_HDR_MODE_VC
    /虚拟通道模式/
    CUS_HDR_MODE_MAX
    注意:
    在旧版的CUS_HDR_MODE_DCG 代表通过虚拟通道传输的HDR,在新版的架构下更名为CUS_HDR_MODE_VC。
    handle->interface_attr.attr_lvds.lvds_hdr_virtual_channel_num 注册设置HDR虚拟通道数根据各个sensor VC模式头文件定义 长曝光帧数:0
    短曝光帧数:1

    4.2.8 Sensor接口注册功能点handle

    表 12:Sensor控制注册功能点列表的handle

    参数 描述 注意
    handle->pCus_sensor_poweron (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    Fill Up Sensor IF Info!!!
    注册设置Sensor上电序列功能点。
    函数引用:
    pCus_poweron
    handle->pCus_sensor_poweroff (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    注册设置Sensor断电序列功能点。
    函数引用:
    pCus_poweroff
    handle->pCus_sensor_init (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS或FAIL
    注册加载Sensor初始设置函数点。
    handle->pCus_sensor_post_init (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    设置并启用 SoC mipi csi 状态。
    特殊情况如 SmartSens 产品 SC4236/SC2315
    handle->pCus_sensor_poweroff (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    注册设置Sensor断电序列功能点。
    函数引用:
    pCus_poweroff
    handle->pCus_sensor_suspend (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    注册设置Sensor暂停功能点。
    handle->pCus_sensor_resume (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    注册设置Sensor恢复功能点。
    handle->pCus_sensor_release (struct __ss_cus_sensor* handle) 参数:
    返回值:SUCCESS 或 FAIL
    注册Sensor释放功能点。
    函数引用:
    cus_camsensor_release_handle
    handle->pCus_sensor_reopen (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    注册设置Sensor重新打开功能点。
    需要移除,pCus_sensor_str resume 替换
    handle->pCus_sensor_streamon (struct __ss_cus_sensor* handle, u32 idx) 参数:
    u32 idx:Sensor Pad
    返回值:SUCCESS 或 FAIL
    注册设置Sensor流开启功能点。
    在Sensor早期初始化模式下,当 vif 设置 streamon 时可以调用该功能点。
    handle->pCus_sensor_GetVideoResNum(struct __ss_cus_sensor* handle, u32 *ulres_num) 参数:
    u32 ulres_num:支持的分辨率列表号
    返回值:SUCCESS或FAIL
    注册获取Sensor支持的分辨率列表号
    函数引用:
    pCus_GetVideoResNum
    handle->pCus_sensor_GetVideoRes (struct __ss_cus_sensor* handle, u32 res_idx, cus_camsensor_res **res) 参数:
    u32 res_idx:分辨率索引
    cus_camsensor_res:请参考 drv_ss_cus_sensor.h
    返回值:SUCCESS 或 FAIL
    注册获取Sensor支持分辨率列表信息函数点。
    handle->pCus_sensor_GetCurVideoRes (struct __ss_cus_sensor* handle, u32 res_idx, cus_camsensor_res **res) 参数:u32 res_idx:分辨率索引 cus_camsensor_res:请参考 drv_ss_cus_sensor.h
    返回值:SUCCESS 或 FAIL
    注册获取Sensor当前分辨率信息功能点。
    handle->pCus_sensor_GetCurVideoRes (struct __ss_cus_sensor* handle, u32 res_idx) 参数:
    u32 res_idx:分辨率索引
    返回值:SUCCESS 或 FAIL
    注册设置Sensor分辨率索引功能点。
    handle->pCus_sensor_GetOrien(struct __ss_cus_sensor* handle, CUS_CAMSENSOR_ORIT *ori) 参数:
    CUS_CAMSENSOR_ORIT:请参考 drv_ss_cus_sensor.h
    返回值:SUCCESS 或 FAIL
    注册获取Sensor mirror-flip状态函数。
    函数引用:
    pCus_GetOrien
    handle->pCus_sensor_SetOrien(struct __ss_cus_sensor* handle, CUS_CAMSENSOR_ORIT ori) 参数:
    CUS_CAMSENSOR_ORIT:请参考 drv_ss_cus_sensor.h
    返回值:SUCCESS 或 FAIL
    注册设置Sensor mirror-flip状态函数。
    函数引用:
    pCus_SetOrien
    handle->pCus_sensor_AEStatusNotify(struct __ss_cus_sensor* handle, u32 idx, CUS_CAMERA_AE_STATUS_NOTIFY status) 参数:
    u32 idx:Sensor Pad
    CUS_CAMERA_AE_STATUS_NOTIFY:请参考 drv_ss_cus_sensor.h
    返回值:SUCCESS 或 FAIL
    注册在帧开始或帧结束时更新 AE 增益、快门和 fps 状态。
    函数引用:pCus_AEStatusNotify
    状态 0 为帧结束更新
    状态 1 为帧开始更新
    handle->pCus_sensor_GetAEUSecs(struct __ss_cus_sensor* handle, u32 *us) 参数:
    u32 *us:AE 快门时间
    返回值:SUCCESS 或 FAIL
    注册获取Sensor输出图像曝光时间。
    函数引用:pCus_GetAEUSecs
    handle->pCus_sensor_SetAEUSecs(struct __ss_cus_sensor* handle, u32 us) 参数:
    u32 us:AE 快门时间
    返回值:SUCCESS 或 FAIL
    注册设置Sensor输出图像曝光时间。
    函数引用:pCus_SetAEUSecs
    handle->pCus_sensor_GetAEGain(struct __ss_cus_sensor* handle, u32 *gain) 参数:
    u32 *gain:AE 增益
    返回值:SUCCESS 或 FAIL
    注册获取Sensor AE 增益。
    函数引用:
    pCus_GetAEGain
    handle->pCus_sensor_SetAEGain(struct __ss_cus_sensor* handle, u32 gain) 参数:
    u32 gain:AE 增益
    返回值:SUCCESS 或 FAIL
    注册设置Sensor AE 增益。
    函数引用:
    pCus_SetAEGain
    handle->pCus_sensor_TryAEGain(struct __ss_cus_sensor* handle, u32 gain) 参数:
    u32 gain:AE 增益
    返回值:SUCCESS 或 FAIL
    注册尝试获取Sensor AE 增益
    handle->pCus_sensor_TryAEShutter(struct __ss_cus_sensor* handle, u32 us) 参数:
    u32 gain : AE shutter
    返回值:SUCCESS 或 FAIL
    注册尝试获取Sensor AE Shutter
    handle->pCus_sensor_GetAEInfo(struct __ss_cus_sensor* handle, CUS_SENSOR_AE_INFO_t *info) 参数:
    CUS_SENSOR_AE_INFO_t:请参考 drv_ss_cus_sensor.h
    返回值:SUCCESS 或 FAIL
    注册尝试获取Sensor AE(快门和增益)信息
    handle->pCus_sensor_GetFPS(struct __ss_cus_sensor* handle) 参数:
    返回值:Sensor fps
    注册获取Sensor FPS 状态函数。
    函数引用:
    pCus_GetFPS
    handle->pCus_sensor_SetFPS(struct __ss_cus_sensor* handle, u32 fps) 参数:
    u32 fps:Sensor fps
    返回值:SUCCESS 或 FAIL
    注册设置Sensor FPS 状态函数。
    函数引用:
    pCus_SetFPS
    handle->pCus_sensor_Get_ShutterGainShare(struct __ss_cus_sensor* handle, int eHDRType) 参数:
    int eHDRType:Sensor fps
    返回值:SUCCESS 或 FAIL
    注册获取Sensor增益和快门状态函数。
    CUS_HDR_MODE_NONE
    /无 HDR/
    CUS_HDR_MODE_SONY_DOL
    /Sony 标准行信息输出/
    CUS_HDR_MODE_DCG
    /双增益 HDR/
    /嵌入式 16 位 HDR/
    CUS_HDR_MODE_COMP
    /压缩 HDR/
    CUS_HDR_MODE_LI
    /行交错 HDR/
    CUS_HDR_MODE_COMP_VS
    /压缩 HDR + very short/
    CUS_HDR_MODE_VC
    /虚拟通道模式/
    CUS_HDR_MODE_MAX
    handle->pCus_sensor_SetISPConverStatus(struct __ss_cus_sensor* handle, u8 bStatus) 参数:
    u8 bStatus : Sensor AE 收敛状态
    返回值:SUCCESS 或 FAIL
    注册设置Sensor AE 收敛状态函数。
    用于快速 AE 收敛模式,可通知 ISP 和 Sensor AE 收敛状态

    4.2.9 从机Sensor handle

    用户可以通过 struct _ms_cus_sensor::slave_mode_attr 设置Sensor handle变量来控制外部从机模式下的 hsync/vsync/trigger 信号时序

    表 13:Sensor从机时序列表的handle

    参数 描述 注意
    handle->slave_mode_attr.eSrcSck 选择 Hsync 时钟源 CUS_CMU_CLK_27MHZ,
    CUS_CMU_CLK_21P6MHZ,
    CUS_CMU_CLK_12MHZ,
    CUS_CMU_CLK_5P4MHZ,
    CUS_CMU_CLK_36MHZ,
    CUS_CMU_CLK_54MHZ,
    CUS_CMU_CLK_43P2MHZ,
    CUS_CMU_CLK_61P7MHZ,
    CUS_CMU_CLK_72MHZ,
    CUS_CMU_CLK_48MHZ,
    CUS_CMU_CLK_24MHZ,
    CUS_CMU_CLK_37P125MHZ*,
    handle->slave_mode_attr.ePolHsync Hsync 初始极性 CUS_CLK_POL_POS,
    CUS_CLK_POL_NEG
    handle->slave_mode_attr.ePolVsync Vsync 初始极性 CUS_CLK_POL_POS,
    CUS_CLK_POL_NEG
    handle->slave_mode_attr.ePolXtrig XTrig 初始极性 CUS_CLK_POL_POS,
    CUS_CLK_POL_NEG
    handle->slave_mode_attr.uHsyncStartT Hsync 开始时间 = uHsyncStartT * 源时钟周期 范围 0 到 65535
    handle->slave_mode_attr.uHsyncEndT Hsync 结束时间 = uHsyncEndT * 源时钟周期 范围 0 到 65535
    handle->slave_mode_attr.uHsyncPeriod Hsync周期 = uHsyncPeriod * 源时钟周期 范围 0 到 65535
    handle->slave_mode_attr.uVsyncEndT Vsync 低时序 = uVsyncEndT * Hsync 周期 范围 0 到 65535
    handle->slave_mode_attr.uVsyncPeriod Vsync 周期 = uVsyncPeriod * Hsync 周期 范围 0 到 65535
    handle->slave_mode_attr.uXTrigEndT XTrigger 低时序 = uXTrigEndT * 源时钟周期 范围 0 到 (2^32)-1
    handle->slave_mode_attr.uXTrigPeriod XTrigger 周期 = uXtrigPeriod * 源时钟周期 范围 0 到 (2^32)-1

    图4:从机模式下的Hsync时序

    图 5:从机模式下的Vsync时序

    4.2.10 自定义功能点handle

    用户可以通过 struct _ms_cus_sensor::slave_mode_attr 设置Sensor handle变量来控制外部从机模式下的 hsync/vsync/trigger 信号时序

    表 14:Sensor用户定义功能点handle列表

    参数 描述 注意
    handle->pCus_sensor_CustDefineFunction(struct __ss_cus_sensor* handle, u32 cmd_id, void *param) 参数:
    cmd_id:用户定义函数项
    *param:用户定义函数参数
    返回值:SUCCESS或FAIL
    注册Sensor增益和快门状态函数。
    请参考第5.7节

    4.2.11 SensorIF 回调的handle

    SENSOR_IF API用于连接Sensor驱动程序和VIF驱动程序,此回调控制在下面的处理控制函数中。

    设置Sensor MCLK 配置

    表 15:sensorif回调函数列表的handle

    参数 描述 注意
    sensor_if->PowerOff(u32 idx, CUS_CLK_POL pol); 参数:
    idx:Sensor Pad
    CUS_CLK_POL:拉高或拉低
    设置 Sensor-IF PowerDown 是否拉高。
    回调至 VIF司机
    sensor_if->Reset(u32 idx, CUS_CLK_POL pol); 参数:
    idx:Sensor Pad
    CUS_CLK_POL:拉高或拉低
    设置 Sensor-IF SW RESET 是否拉高。
    回调至VIF 驱动程序
    sensor_if->MCLK(u32 idx , u8 bon_off, CUS_MCLK_FREQ mclk); 参数:
    idx:Sensor Pad
    bon_off:启用或禁用
    CUS_MCLK_FREQ:Sensor clk
    注册设置 VIF 模块输出 MCLK 到Sensor用于 MI 查询!!
    主芯片支持 MCLK 列表为:
    CUS_CMU_CLK_27MHZ,
    CUS_CMU_CLK_21P6MHZ,
    CUS_CMU_CLK_12MHZ,
    CUS_CMU_CLK_5P4MHZ,
    CUS_CMU_CLK_36MHZ,
    CUS_CMU_CLK_54MHZ,
    CUS_CMU_CLK_43P2MHZ,
    CUS_CMU_CLK_61P7MHZ,
    CU S_CMU_CLK_72MHZ,
    CUS_CMU_CLK_48MHZ,
    CUS_CMU_CLK_24MHZ,
    CUS_CMU_CLK_37P125MHZ,
    CUS_CMU_CLK_LPLL_DIV1,
    CUS_CMU_CLK_LPLL_DIV2,
    CUS_CMU_CLK_LPLL_DIV4,
    CUS_CMU_CLK_LPLL_DIV8,
    sensor_if->SetIOPad (u32 idx, CUS_SENIF_BUS ulSnrType, NULL) 参数:
    idx:Sensor Pad
    CUS_SENIF_BUS:Sensor接口
    用于 SENSOR-IF I/O 总线模式
    回调至 VIF 驱动程序
    sensor_if->SetSkipFrame(u32 idx, u16 skip_num, u8 bon_off) 参数:
    idx:Sensor Pad
    skip_num:跳过帧cnt
    bon_off:启用或禁用
    跳过vif输出帧
    回调至VIF驱动程序

    4.2.12 MIPI CSI配置回调的handle

    SENSOR_IF API 用于连接Sensor驱动程序和 MIPI CSI 驱动程序,此回调控制在下面的处理控制函数中。

    表16:mipi csi回调函数列表

    参数 描述 注意
    sensor_if->SetCSI_Clk (u32 idx, CUS_CSI_CLK clk) 参数:
    idx:Sensor Pad
    CUS_CSI_CLK:Mipi clk
    设置 MIPI 接口 MAC CLK
    回调至 CSI 驱动程序
    sensor_if->SetCSI_Lane(u32 idx, u16 num_lane, u8 bon_off) 参数:
    idx:Sensor Pad
    num_lane:Mipi 通道号
    bon_off:启用或禁用
    设置 MIPI 接口数据通道
    回调至 CSI 驱动程序
    sensor_if->SetCSI_hdr_mode(idx, CUS_HDR_MODE hdr_mode, u8 bon_off) 参数:
    idx:Sensor Pad
    hdr_mode:
    bon_off:启用或禁用
    设置 HDR 数据格式
    回调到 CSI 驱动程序
    CUS_HDR_MODE_NONE
    /无 HDR/
    CUS_HDR_MODE_SONY_DOL
    /Sony 标准线信息输出/
    CUS_HDR_MODE_DCG
    /双增益 HDR/
    /嵌入式 16 位 HDR/
    CUS_HDR_MODE_COMP
    /压缩 HDR/
    CUS_HDR_MODE_LI
    /线交错 HDR/
    CUS_HDR_MODE_COMP_VS
    /压缩 HDR + very short/
    CUS_HDR_MODE_VC
    /虚拟通道模式/
    CUS_HDR_MODE_MAX
    sensor_if->SetCSI_LongPacketType(u32 idx, u16 dt0_15, u16 dt16_31, u16 u32_47) 参数:
    idx:Sensor Pad
    类型[15:0],[31:16],[47:32]
    设置 MIPI 长数据包类型启用
    回调至 CSI 驱动程序长数据包类型启用
    [0]: Null
    [1]: blinking
    [2]: embedded
    [14]: YUV422_8B
    [26]: RAW8
    [27]: RAW10
    [28]: RAW12
    [29]: RAW14
    [30]: RAW16
    [32]: UD1
    [33]: UD2
    [34]: UD3
    [35]: UD4
    [36]: UD5
    [37]: UD6
    [38]: UD7
    [39]: UD8
    Sensor_if->SetCSI_yuv_order_swap(u32 idx, u8 swap) 参数:
    idx:Sensor Pad
    swap:启用或禁用
    设置 MIPI 输入 YUV422 数据顺序交换
    回调至 CSI 驱动程序

    4.2.13 Parallel极性回调handle

    设置Parallel Sensor硬件信号极性

    表 17:Parallel Sensor回调函数列表

    参数 描述 注意
    Sensor_if-> SetVIF_ParPinPol(u32 idx, CUS_CLK_POL HsynPol, CUS_CLK_POL VsynPol) 参数:
    u32 idx:Sensor Pad
    HsynPol:parallel sensor hsync 极性
    VsynPol:parallel sensor vsync 极性
    用于Sensor vysnc 和 hsync 极性配置
    回调至 VIF 驱动程序

    4.2.14 私有数据

    本章介绍Sensor驱动私有数据,目的是记录Sensor的参数,不做任何修改。这里以imx415作为参考例子。

    首先,Sgs Sensor驱动程序将在安装Sensor时配置存储库。

    SENSOR_DRV_ENTRY_IMPL_END_EX(  IMX415_HDR,
                                  cus_camsensor_init_handle,
                                  cus_camsensor_init_handle_hdr_dol_sef,
                                  cus_camsensor_init_handle_hdr_dol_lef,
                                  imx415_params
                                  );
    

    该内存根据sensor驱动来声明,以imx415为例:

    ​typedef struct {
        struct {
            bool bVideoMode;
            u16 res_idx;
            CUS_CAMSENSOR_ORIT  orit;
        } res;
        struct {
            float sclk;
            u32 hts;
            u32 vts;
            u32 us_per_line;
            u32 final_us;
            u32 final_gain;
            u32 fps;
            u32 preview_fps;
            u32 expo_lines;
            u32 expo_lef_us;
            u32 expo_sef_us;
            u32 expo_sef2_us;
        } expo;
        u32 min_shr1;
        u32 min_rhs1;
        u32 min_shr2;
        u32 min_rhs2;
        u32 min_shr0;
        u32 max_shr0;
        u32 fsc;
        u32 skip_cnt;
        I2C_ARRAY tVts_reg[3];
        I2C_ARRAY tVts_reg_hdr[3];
        I2C_ARRAY tExpo_reg[3];
        I2C_ARRAY tSHR0_reg[3];
        I2C_ARRAY tSHR1_reg[3];
        I2C_ARRAY tRHS1_reg[3];
        I2C_ARRAY tSHR2_reg[3];
        I2C_ARRAY tRHS2_reg[3];
        I2C_ARRAY tGain_reg[2];
        I2C_ARRAY tGain_hdr_dol_lef_reg[2];
        I2C_ARRAY tGain_hdr_dol_sef_reg[2];
        I2C_ARRAY tGain_hdr_dol_sef2_reg[2];
        bool dirty;
        bool orien_dirty;
        u8 snr_pad;
        const I2C_ARRAY *pTable_linear;
        const I2C_ARRAY *pTable_HDR;
        u32 Init_Array_Size;
        u32 Init_Vts;
        u32 Line_Period;
        u32 csi_clk;
        u32 PowerOnOff;
        CUS_CAMSENSOR_ORIT orient;
    } imx415_params;
    

    接下来我们在挂载Sensor寄存器函数时,将缓冲区配置为imx415_params:

    ​int cus_camsensor_init_handle_linear(ss_cus_sensor* drv_handle)
    {
        ss_cus_sensor *handle = drv_handle;
        imx415_params *params;
        int res;
    
        if (!handle) {
            SENSOR_DMSG("[%s] not enough memory!\n", __FUNCTION__);
            return FAIL;
        }
        SENSOR_DMSG("[%s]", __FUNCTION__);
        ////////////////////////////////////
        // private data allocation & init //
        ////////////////////////////////////
        if (handle->private_data == NULL) {
            SENSOR_EMSG("[%s] Private data is empty!\n", __FUNCTION__);
            return FAIL;
        }
    
        params = (imx415_params *)handle->private_data;
        CamOsMemcpy(params->tVts_reg, vts_reg, sizeof(vts_reg));
        CamOsMemcpy(params->tGain_reg, gain_reg, sizeof(gain_reg));
        CamOsMemcpy(params->tExpo_reg, expo_reg, sizeof(expo_reg));
    …
    …
    

    4.2.15 通用Sensor从机模式控制 API

    使用通用从机模式函数 struct _ms_cus_sensor::sensor_if_api::SlaveModeCtrl 允许用户对信号时序控制进行更详细的设置。您可以在 drv_ms_cus_imx226_lvds.c 中找到示例代码和更多详细信息

    控制 ID 描述 注意
    CUS_SLAVE_MODE_CTRL_ID_INIT 初始化 Hsync 和 Vsync CUS_SLAVE_MODE_CTRL_ID_INIT
    CUS_SLAVE_MODE_CTRL_ID_DEINIT 释放并禁用 Hsync 和 Vsync CUS_SLAVE_MODE_CTRL_ID_DEINIT
    CUS_SLAVE_MODE_CTRL_ID_ENABLE_XVS 立即启用或禁用 Vsync CUS_SLAVE_MODE_CTRL_ID_ENABLE_XVS

    5. 软件移植流程

    本章介绍软件移植Sensor驱动的过程。首先讲解如何初始化Sensor。然后描述Sensor驱动3A所需的信息以及控制3A将调用的函数。

    5.1. Sensor驱动初始流程介绍

    图 6:移植Sensor驱动程序流程

    本文档按照上图的流程介绍了Sensor移植的初始过程。

    5.1.1 设置Sensor信息

    这些设置都是sensor的硬件信息,我们列出了必要的硬件信息,大家可以参考IMX415/IMX335 sensor驱动。

    ////////////////////////////////////
    // Sensor-If Info                 //
    ////////////////////////////////////
    //MIPI config begin.
    #define SENSOR_MIPI_LANE_NUM        (lane_num)          //IMX335 Linear mode supports MIPI 2/4 Lane
    #define SENSOR_MIPI_LANE_NUM_DOL    (4) //(hdr_lane_num)//IMX335 DOL mode supports MIPI 4 Lane
    #define SENSOR_IFBUS_TYPE           CUS_SENIF_BUS_MIPI  //CFG //CUS_SENIF_BUS_PARL, CUS_SENIF_BUS_MIPI
    #define SENSOR_DATAPREC             CUS_DATAPRECISION_10
    #define SENSOR_DATAPREC_DOL         CUS_DATAPRECISION_10
    #define SENSOR_BAYERID              CUS_BAYER_RG         //0h: CUS_BAYER_RG, 1h: CUS_BAYER_GR, 2h: CUS_BAYER_BG, 3h: CUS_BAYER_GB
    #define SENSOR_BAYERID_HDR_DOL     CUS_BAYER_RG
    #define SENSOR_RGBIRID              CUS_RGBIR_NONE
    CUS_ORIT_M1F1,
    //#define SENSOR_YCORDER              CUS_SEN_YCODR_YC     //CUS_SEN_YCODR_YC, CUS_SEN_YCODR_CY
    //#define long_packet_type_enable     0x00 //UD1~UD8 (user define)
    
    ////////////////////////////////////
    // MCLK Info                        //
    ////////////////////////////////////
    #define Preview_MCLK_SPEED          CUS_CMU_CLK_27MHZ//CUS_CMU_CLK_37P125MHZ//CUS_CMU_CLK_27MHZ
    #define Preview_MCLK_SPEED_HDR_DOL  CUS_CMU_CLK_27MHZ
    

    5.1.2 设置Sensor I2C

    SoC主要通过I2C与Sensor进行通信,因此在将Sensor设置值发送给Sensor之前,需要先设置I2C。

    请参阅本文档 第 1.2 章

    5.1.3 设置支持图片分辨率信息

    需要填写Sensor提供商FAE提供的Sensor图片信息,包括预览尺寸、图片裁剪尺寸、站点等,我们将这些信息定义为全局变量。

    ////////////////////////////////////
    // Image Info                     //
    ////////////////////////////////////
    static struct {     // LINEAR
        // Modify it based on number of support resolution
        enum {LINEAR_RES_1 = 0, LINEAR_RES_2, LINEAR_RES_3, LINEAR_RES_4, LINEAR_RES_5, LINEAR_RES_6, LINEAR_RES_7, LINEAR_RES_8, LINEAR_RES_END}mode;
        // Sensor Output Image info
        struct _senout{
            s32 width, height, min_fps, max_fps;
        }senout;
        // VIF Get Image Info
        struct _sensif{
            s32 crop_start_X, crop_start_y, preview_w, preview_h;
        }senif;
        // Show resolution string
        struct _senstr{
            const char* strResDesc;
        }senstr;
    }imx415_mipi_linear[] = {
        {LINEAR_RES_1, {3860, 2250, 3, 20}, {0, 0, 3840, 2160}, {"3840x2160@20fps"}},
        {LINEAR_RES_2, {3096, 2190, 3, 30}, {0, 0, 3072, 2048}, {"3072x2048@30fps"}}, // Modify it
        {LINEAR_RES_3, {3096, 1758, 3, 30}, {0, 0, 3072, 1728}, {"3072x1728@30fps"}}, // Modify it
        {LINEAR_RES_4, {2616, 1974, 3, 30}, {0, 0, 2592, 1944}, {"2592x1944@30fps"}}, // Modify it
        {LINEAR_RES_5, {2976, 1686, 3, 30}, {0, 0, 2944, 1656}, {"2944x1656@30fps"}}, // Modify it
        {LINEAR_RES_6, {2592, 1470, 3, 30}, {0, 0, 2560, 1440}, {"2560x1440@30fps"}}, // Modify it
        {LINEAR_RES_7, {1920, 1080, 3, 60}, {0, 0, 1920, 1080}, {"1920x1080@60fps"}}, // Modify it
        {LINEAR_RES_8, {3864, 2192, 3, 30}, {0, 0, 3840, 2160}, {"3840x2160@30fps"}}, // Modify it
        //{LINEAR_RES_9, {2616, 1974, 3, 25}, {0, 0, 2592, 1944}, {"2592x1944@25fps"}}, // Modify it
    };
    

    5.1.4 Sensor上电时序功能

    请参考“handle->pCus_sensor_poweron”注册的函数。

    5.1.5 Sensor初始化函数

    这里是通过i2c设备对Sensor进行初始设置,首先读取Sensor设备的产品ID或者Sensor ID,确保使用了正确的Sensor。请参考“handle->pCus_sensor_init”注册的函数。

    5.1.6 选择Sensor输出分辨率函数

    MI 将获取Sensor驱动程序支持的图像分辨率信息,并选择Sensor的初始设置之一。

    请参考“handle->pCus_sensor_SetVideoRes”注册的函数。

    5.1.7 Sensor断电时序功能

    请参考“handle->pCus_sensor_poweroff”注册的函数。

    5.2. 实现Sensor控制功能

    sensor驱动需要支持的功能有fps的调整、AE快门的调整、AE增益的调整以及mirror-flip功能的设置等,这需要根据各个sensor的特点来实现。

    以下是我们控制Sensor实现的函数流程。相对的,我们还需要获取Sensor的信息,请参考下图:

    图7:控制Sensor实现功能流程

    图8:获取Sensor实现功能信息或状态

    5.2.1 AE快门控制并获取AE快门信息

    如何控制AE快门,请参考“handle->pCus_sensor_SetAEUSecs”注册的函数。

    另外,ISP 算法或者 MI 需要获取 AE 快门信息,请参考“handle->pCus_sensor_GetAEInfo”注册的函数。

    5.2.2 AE增益控制及获取AE增益信息

    如何控制AE增益,请参考“handle->pCus_sensor_SetAEGain”注册的函数。

    另外,ISP 算法或者 MI 需要获取 AE 增益信息,请参考“handle->pCus_sensor_GetAEInfo”注册的函数

    更多详细信息请参考 5.2.6 和 5.2.7。

    5.2.3 Sensor帧率控制并获取Sensor帧率信息

    如何控制sensor输出帧率,请参考“handle->pCus_sensor_SetFPS”注册的函数。

    另外MI需要获取sensor输出帧率信息,请参考“handle->pCus_sensor_GetFPS”注册的函数。

    5.2.4 Sensor mirror-flip控制及获取Sensor mirror-flip信息

    如何控制sensor图像镜像翻转,请参考“handle->pCus_sensor_SetOrien”注册的函数。

    另外,MI需要获取Sensor图像镜像翻转信息,请参考“handle->pCus_sensor_GetOrien”注册的函数。

    5.2.5 I2C执行时间控制

    上面的AE快门、AE增益、sensor帧率和反光镜控制,希望大家可以同时通过I2C给sensor发送命令

    因此我们将使用函数“handle->pCus_sensor_AEStatusNotify”来实现这一点

    因此我们可以通过两个参数“CUS_FRAME_ACTIVE”和“CUS_FRAME_INACTIVE”来控制I2C向Sensor发送命令的时间。大部分Sensor都可以在帧开始时设置,因此可以选择参数“CUS_FRAME_ACTIVE”。

    图 9:I2C 执行时间

    注意:

    如果移植Sensor无法找出导致图像异常的原因,可以直接在函数中调用返回成功。

    5.2.6 Sensor AE 快门/增益延迟计数

    如何设置“ae shutter delay” 和 “ae gain delay” 的“handle->pCus_sensor_GetAEInfo”,请参考本文档 第 4.3 章

    5.2.7 Sensor AE 快门/增益控制数字

    “ae gain ctrl num” 和 “ae shutter ctrl num” 的“ handle->pCus_sensor_GetAEInfo” 表示可以控制 AE 流数量的 ISP

    获取AE信息示例代码:

    static int pCus_sensor_GetAEInfo(ss_cus_sensor *handle, CUS_SENSOR_AE_INFO_t *info)
    {
        imx415_params *params = (imx415_params *)handle->private_data;
    
        info->u8AEGainDelay                      = SENSOR_GAIN_DELAY_FRAME_COUNT;
        info->u8AEShutterDelay                   = SENSOR_SHUTTER_DELAY_FRAME_COUNT;
        info->u8AEGainCtrlNum                    = SENSOR_GAIN_CTRL_NUM;
        info->u8AEShutterCtrlNum                 = SENSOR_SHUTTER_CTRL_NUM;
        info->u32AEGain_min                      = SENSOR_MIN_GAIN;
        info->u32AEGain_max                      = SENSOR_MAX_GAIN;
        info->u32AEShutter_min                   = params->Line_Period * 1;
        info->u32AEShutter_max                   = 1000000000/handle->video_res_supported.res[handle->video_res_supported.ulcur_res].u16min_fps;
        info->u32AEShutter_step                  = params->Line_Period;
        return SUCCESS;
    }
    

    6. 补充

    6.1. 安装Sensor Driver及参数介绍

    Sgs Sensor驱动提供了几个安装参数,安装Sensor驱动时可以使用这些参数,具体参数及说明如下:

    表 17:Sensor驱动安装参数

    参数 描述
    chmap 指定Sensor的 SoC Channel pad,以bitmap格式表示,Bit[0]代表sensor 0,Bit[1]代表sensor 1,依此类推。
    mclk 指定Sensor mclk 信息
    lane_num 指定 Sensor 线性模式 MIPI 通道数
    hdr_lane_num 指定Sensor hdr 模式 MIPI 通道号
    i2c_slave_id 指定Sensor i2c 从机 id

    例如:

    insmod imx335_MIPI.ko chmap=1 lane_num=4 hdr_lane_num=4 i2c_slave_id=0x20
    

    如果安装Sensor驱动时没有使用以上参数,则使用Sensor驱动中的默认值。

    6.2. 验证快门和增益延迟

    如果要验证Sensor AE 增益/快门延迟,可以使用 apitool,同样按照下面的步骤逐步控制Sensor AE 增益/快门功能。

    步骤 1. 您需要先执行 prog_vif_isp_ut 进程

    /customer # ./prog_vif_isp_ut param_snr0.ini
    

    步骤 2. 在 sdk 路径“project/tools/apitool”中打开 IQ 工具

    步骤 3. 主机名是 EVB 的 IP 地址,检查后连接到 EVB

    步骤 4. 选择 Macaron AE 选项,并将“ExposureMode”菜单表选择为 M_Mode

    步骤 5. 调整“DebugLev”菜单并将 AE 调试级别从 0 设置为 64,然后您就可以检查控制台日志

    检查控制台上显示的 AE 消息

    步骤 6. 手动调整 AE Sensor增益或快门。同时,您可以观察控制台上显示的 AE 消息。

    观察“CurYx10”的值从 308 变为 1436

    我们通过ISP工具设置AE的增益后,会在下一帧生效,CurYx10代表的是前一帧的亮度信息,下图为示例,AE增益延时需要设置2。

    图10:AE Y值响应时间

    6.3. 验证快门和增益线性

    移植完sensor AE gain/shutter功能后,如果想验证sensor AE gain/shutter功能是否正常,可以使用apitool,可以按照下面的步骤控制sensor AE gain/shutter功能。

    步骤 1. 执行mixer

    /customer # ./prog_vif_isp_ut param_snr0.ini
    

    步骤 2. 在 sdk 路径“project/tools/apitool”中打开 IQ 工具

    步骤 3. 主机名是 EVB 的 IP 地址,检查后连接到 EVB

    步骤 4. 选择 Macaron AE 选项,并将“ExposureMode”菜单表选择为 M_Mode

    步骤 5. 手动调整 AE Sensor增益和快门。同时,您可以通过 VLC 或调试消息观察图像变化。

    IQ Tool 已定义 AE 设置的上限和下限,您可以根据需要进行调整。您可以参考曝光限制表。

    6.4. 跳帧功能

    目前已经实现的sensor驱动有imx307,可以参考imx307的sensor驱动,这里我简单讲一下skip frame功能的使用方法。

    步骤 1. 在Sensor驱动程序的 Params 结构中添加一个变量“skip _cnt”

        u32 max_rhs1;
        u32 lef_shs2;
        u32 skip_cnt;
        bool dirty;
        bool change;
        I2C_ARRAY tVts_reg[3];
        I2C_ARRAY tGain_reg[3];
        I2C_ARRAY tExpo_reg[3];
        I2C_ARRAY tShs2_reg[3];
        I2C_ARRAY tRhs1_reg[3];
        I2C_ARRAY tGain_hdr_dol_lef_reg[1];
        I2C_ARRAY tGain_hdr_dol_sef_reg[1];
        bool orien_dirty;
    } imx307_params;
    

    步骤2. 在需要跳帧的函数中设置跳帧的数量。

    以imx307为例,在HDR模式下,高亮环境下改变fps(从10 fps到30 fps)可能会出现闪烁,因此请跳过1帧以避免闪烁。

    if(params->expo.expo_lines > 2 * params->expo.vts - params->max_rhs1 -3){
        vts = (params->expo.expo_lines + params->max_rhs1 + 3 + 1) / 2;
    }else{
        vts = params->expo.vts;
    }
    
    params->expo.vts = vts;
    pCus_SetAEUSecsHDR_DOL_SEF1(handle, params->expo.expo_sef_us);
    params->skip_cnt = 1;
    return SUCCESS;
    

    步骤 3. “AESStatusNotify” 函数中实际跳帧时间。请添加以下功能。SensorIF 将根据跳帧数和当前 fps 时间段计算设置 VIF 掩码禁用的时间。

            if(params->skip_cnt){
                sensor_if->SetSkipFrame(handle->snr_pad_group, params->expo.fps, params->skip_cnt);
                params->skip_cnt = 0;
            }
            break;
        default :
                break;
    }
    return SUCCESS;
    

    6.5. Sensor初始后功能(SmartSens 的特殊情况)

    由于Smartsens sensor上电后先传输i2c cmd,有概率sensor的mipi csi和clock会被拉低,导致SoC mipi csi异常。

    图 11:Smartsense Sensor信号

    目前解决办法是改变sensor上电和sensor初始化的顺序,等sensor初始化完成后再使能SoC mipi csi即可解决这个问题,具体流程请参考如下:

    图12:开机顺序流程变化

    注意:

    还有其他方法可以解决这个问题,请要求Sensor厂商提供 mipi csi非连续模式,可以解决由于mipi csi首帧接收状态异常导致mipi csi卡死的问题。

    6.6. Parallel Sensor配置

    Parallel Sensor 相较于 MIPI Sensor,需要确认信号极性与硬件 Pin 排列,下面将说明如何设定信号极性与硬件 Pin 排列。

    6.6.1 Parallel Sensor信号极性

    一般Parallel Sensor通常需要配置3种时钟信号

    表 18:Parallel Sensor信号类型

    信号名称 缩写 描述
    Vertical Sync VSYNC Frame Start (FS)
    Horizontal Sync HSYNC Line Start (LS)
    Pixel Clock PCLK Carry Pixel data

    Frame Start (FS) 信号在 VSYNC 的上升沿或下降沿生成。Line Start (LS) 信号在 HSYNC 的上升沿或下降沿生成,PCLK 内部进行 AND 运算以提供有效的像素时钟信号。VSYNC 和 HSYNC 可以是高电平有效或低电平有效。在每个有效的像素时钟沿,数据都会被锁存到 FIFO 中。

    图 13:Parallel Sensor信号

    我们在Sensor驱动程序中提供了 API 来配置Parallel Sensor vsync 和 hsync 极性。它需要根据Sensor初始化设置来配置极性。参考:

    int (*SetVIF_ParPinPol) (u32 idx, CUS_CLK_POL HsyncPol, CUS_CLK_POL VsyncPol);

    static int pCus_poweron(ss_cus_sensor *handle, u32 idx)
    {
        ISensorIfAPI *sensor_if = handle->sensor_if_api;
    
        //Sensor power on sequence
        sensor_if->PowerOff(idx, CUS_CLK_POL_NEG);   // Powerdn Pull Low
        sensor_if->Reset(idx, CUS_CLK_POL_NEG);     // Rst Pull Low
        sensor_if->SetVIF_ParPinPol(idx, CUS_CLK_POL_NEG);     // Rst Pull Low
        sensor_if->SetIOPad(idx, handle->sif_bus, CUS_CLK_POL_NEG, CUS_CLK_POL_NEG);
    

    6.6.2 Parallel Sensor Pad布局

    Parallel Sensor配置需要根据Sensor Pad的排列来确定Sensor格式,而不是使用Sensor数据精度

    示例1(8-bit Sensors):

    Parallel padmux模式提供2组设置,8-bit Sensors的布局如下:红框/蓝框/橙框。硬件上布局不同,则设置的sensor格式会有所不同。

    图 14:8-bit Parallel Sensor布局

    示例2(10-bit Sensors)

    Parallel padmux 模式提供 2 组设置,10-bit Sensors 的布局如下:蓝色框/橙色框。硬件上布局不同,则设置的 Sensor 格式会有所不同。

    图 15:10-bit Parallel Sensor布局

    VIF 配置Sensor格式始终为 12 位,建议硬件parallel数据引脚按 MSB 方向排列。如果不是,那么我们在 DTS 文件中提供了 MSB 移位参数设置 “vif_sr0_par_msb_shift=shift_pin”

    硬件限制:shift_pin 只能是 2/4/6

    6.7. 客户功能

    如果用户想为Sensor驱动实现定制化的函数或者获取Sensor的信息,Sgs Sensor驱动提供了寄存器功能点供客户根据自己的需求进行开发,客户可以利用这些函数自定义内容:

    图 16:用户定义控制流

    Sensor驱动程序中的用户定义实现:

    #define CMDID_I2C_READ   (0x01)
    #define CMDID_I2C_WRITE  (0x02)
    
    static int pCus_sensor_CustDefineFunction(ss_cus_sensor* handle,u32 cmd_id, void *param) {
    
        if(param == NULL || handle == NULL)
        {
            SENSOR_EMSG("param/handle data NULL \n");
            return FAIL;
        }
    
        switch(cmd_id)
        {
            case CMDID_I2C_READ:
            {
                I2C_ARRAY *reg = (I2C_ARRAY *)param;
                SensorReg_Read(reg->reg, &reg->data);
                SENSOR_EMSG("reg %x, read data %x \n", reg->reg, reg->data);
                break;
            }
            case CMDID_I2C_WRITE:
            {
                I2C_ARRAY *reg = (I2C_ARRAY *)param;
                SENSOR_EMSG("reg %x, write data %x \n", reg->reg, reg->data);
                SensorReg_Write(reg->reg, reg->data);
                break;
            }
            default:
                SENSOR_EMSG("cmd id %d err \n", cmd_id);
                break;
        }
    
        return SUCCESS;
    }
    

    7. 故障排除

    7.1. SONY Sensor输出格式

    Sony sensor输出的mipi格式有两种,分别是DOL或VC,Sgs的mipi csi会根据settings比较头文件来接收数据,所以请确认当前的sensor初始化设置。

    7.2. VIF 状态

    同时可以打开telnet,输入下面的cmd来确认VIF和ISP状态。

    通常30fps意味着一帧周期为33.3ms。

    / # cat /proc/mi_modules/mi_vif/debug_hal/vif0/vif_ints
    == VIF0 INTS @:58129759 ==
    == VIF CH-0 ==
    CH State:                       : WORKING
    Interval(us)                    : 41672
    FramePeriod(us)                 : 39057
    VREF_FALLING                    : 691 @:58099735
    LINE_CNT_0                      : 0 @:0
    LINE_CNT_1                      : 0 @:0
    TOTAL_PIX_CNT                   : 670 @:58097120
    
    == VIF CH-1 ==
    CH State:                       : WORKING
    Interval(us)                    : 41670
    FramePeriod(us)                 : 39041
    VREF_FALLING                    : 691 @:58102994
    LINE_CNT_0                      : 0 @:0
    LINE_CNT_1                      : 0 @:0
    TOTAL_PIX_CNT                   : 670 @:58100365
    
    == VIF FIFO-0 ==
    Aff State:                      : WORKING
    AFF Count:                      : 0 @:0
    
    == VIF FIFO-1 ==
    Aff State:                      : WORKING
    AFF Count:                      : 0 @:0
    
    == VIF FIFO-2 ==
    Aff State:                      : READY
    AFF Count:                      : 0 @:0
    
    == VIF FIFO-3 ==
    Aff State:                      : READY
    AFF Count:                      : 0 @:0
    

    确认VIF设备接收到的Sensor信号信息

    / # cat /proc/mi_modules/mi_vif/debug_hal/vif0/vif_info
    == VIF0 INFO @:49165780 ==
    == VIF CH-0 ==
    CH State:: WORKING
    [vg:0 link:REAL_ISP]--[chn:0]--[afifo:1]--[pipe:1(1)]--[isp:1]--[end]
    CH_EN: 1
    SRC: MIPI0
    INPUT_FMT: RGB
    PIX_FMT: 10 bits
    CROP_EN: 1
    CROP_START_X: 0 - 3839
    CROP_START_Y: 0 - 2159
    PIXEL_CNT: 3840
    LINE_CNT: 2160
    TOTAL_PIXEL_CNT: 3864
    TOTAL_LINE_CNT: 2192
    
    == VIF CH-1 ==
    CH State:: WORKING
    [vg:0 link:REAL_ISP]--[chn:1]--[afifo:0]--[pipe:0(0)]--[isp:0]--[end]
    CH_EN: 1
    SRC: MIPI0
    INPUT_FMT: RGB
    PIX_FMT: 10 bits
    CROP_EN: 1
    CROP_START_X: 0 - 3839
    CROP_START_Y: 0 - 2159
    PIXEL_CNT: 3840
    LINE_CNT: 2160
    TOTAL_PIXEL_CNT: 3864
    TOTAL_LINE_CNT: 2192
    

    7.3. MIPI 状态

    如果每帧一行或一个像素的传输速度太快,即便VIF能正常接收到图像数据,也不能保证ISP能立刻处理,从而导致isp fifo full。

    / # echo 0 0 > /proc/mi_modules/mi_sensor/debug_hal/csi_dbg_mask
    / # cat /proc/mi_modules/mi_sensor/debug_hal/csi_ints
    

    注意:

    echo “Sensor Pad” “mask_status” > /proc/mi_modules/mi_sensor/debug_hal/csi_dbg_mask

    == MIPI pad0 err ints==
    DT      : 22569
    PA_LENS : 0
    PH_LENS : 0
    ECC_ONEBIT      : 0
    FRAME_START     : 0
    FRAME_END       : 0
    ECC_TWOBIT      : 0
    CRC     : 0
    PA_WC_EQ0       : 0
    RAW10_LENS      : 0
    CON_FE  : 0
    CON_FS  : 0
    LE      : 0
    LS      : 0
    OVERRUN : 0
    == MIPI pad0 rtp ints==
    LINE_NUM        : 0
    FRAME_NUM       : 0
    SHORT_PKT       : 0
    VC3_DONE        : 0
    VC2_DONE        : 0
    VC1_DONE        : 0
    VC0_DONE        : 0
    
    
    == MIPI pad1 err ints==
    DT      : 75
    PA_LENS : 0
    PH_LENS : 0
    ECC_ONEBIT      : 0
    FRAME_START     : 0
    FRAME_END       : 0
    ECC_TWOBIT      : 0
    CRC     : 0
    PA_WC_EQ0       : 0
    RAW10_LENS      : 0
    CON_FE  : 0
    CON_FS  : 0
    LE      : 0
    LS      : 0
    OVERRUN : 0
    == MIPI pad1 rtp ints==
    LINE_NUM        : 0
    FRAME_NUM       : 0
    SHORT_PKT       : 0
    VC3_DONE        : 0
    VC2_DONE        : 0
    VC1_DONE        : 0
    VC0_DONE        : 0
    
    
    == MIPI pad2 err ints==
    DT      : 0
    PA_LENS : 0
    PH_LENS : 0
    ECC_ONEBIT      : 0
    FRAME_START     : 0
    FRAME_END       : 0
    ECC_TWOBIT      : 0
    CRC     : 0
    PA_WC_EQ0       : 0
    RAW10_LENS      : 0
    CON_FE  : 0
    CON_FS  : 0
    LE      : 0
    LS      : 0
    OVERRUN : 0
    == MIPI pad2 rtp ints==
    LINE_NUM        : 0
    FRAME_NUM       : 0
    SHORT_PKT       : 0
    VC3_DONE        : 0
    VC2_DONE        : 0
    VC1_DONE        : 0
    VC0_DONE        : 0
    

    Mipi csi中断错误消息

    • OVERRUN:lane 时钟域到 mpll 时钟域 asyn fifo 溢出
    • LS:收到行结束但丢失行开始错误
    • LE:收到行首但丢失行尾错误
    • CON_FS: 两个共同的帧开始之间没有帧结束
    • CON_FE: 两个连续帧结束之间没有帧开始
    • RAW10_LENS: tie 0(未使用)
    • PA_WC_EQ0: 数据包头中的有效载荷字数等于 0
    • CRC:数据包有效载荷CRC校验结果错误
    • ECC_TWOBIT:数据包头ECC校验结果有2-bit错误
    • FRAME_END:帧起始数据包后没有帧结束数据包
    • FRAME_START(硬件自动忽略):收到一个正常数据包,但之前没有帧起始包
    • ECC_ONIVIT:数据包头ECC校验结果有1-bit错误
    • PH_LENS:数据包头长度错误
    • PA_LENS: 有效载荷长度错误比 wc 短
    • DT:保留且不支持的数据类型