Sensor移植
默认SDK的SensorDriver下会提供点过的code,在确定Sensor型号后先在SensorDriver目录下找到有没有同厂家类型的code。如果有相同厂家的code,找相近的型号复制一份代码,并更名为所用的型号,在此基础上去修改代码。
1 Sensor初始化¶
以下以GC1054为例,对应code文件为drv_ms_cus_gc1054_MIPI.c,介绍如何来点亮一颗Sensor。
1.1 Sensor上电时序¶
首先要启动Sensor,需要对照Sensor规格书上的上电时序,保证上电时序满足规格书的要求。如果上电时序不对,与Sensor的I2C通信也将会出错,因为Sensor本来就没正常按时序启动,I2C通讯报错是必然的。一般来说在规格书上,搜索关键字“poweron”、“powerup”、“power on”、“power up”或者直接查看规格书上的目录,就能够查找到Sensor的上电时序。
在软件驱动代码上,是通过handle->pCus_sensor_poweron接口来控制对sensor的上电时序。驱动文件中对这个接口进行了注册,如下图:
实际上电最终调用的是pCus_poweron这一函数。对pwdn和reset的极性定义如下图:
即当调用sensor_if->PowerOff(idx, handle->pwdn_POLARITY)
时是对PWDN脚置高电平,调用sensor_if->PowerOff(idx, !handle->pwdn_POLARITY)
是对PWDN脚置低电平;调用sensor_if->Reset(idx, handle->reset_POLARITY)
是对RESET脚置低电平,调用sensor_if->Reset(idx, !handle->reset_POLARITY)
是对RESET脚置高电平。
驱动代码与规格书的上电时序对应关系如下:
规格书上的参数说明如下:
没有对最大时间做一个限制,因此每次控制电平不小于50us即可,也尽量比可允许的最小值大些,不要过于临界。
1.2 Sensor的I2C从地址¶
在Sensor按照规格书上的上电时序启动后,芯片会通过I2C和Sensor进行通讯,要在规格书上确认好Sensor的I2C从地址。注意,在驱动中所填写的I2C从地址是包含读写位的,规格书上与驱动代码的对应关系如下:
如果确认上电时序无误,在Sensor启动后仍然如下的I2C报错,就需要检查I2C的从地址是否正确。
ERROR: Bus[1] in ms_i2c_xfer_write: Slave dev NAK, Addr: 0x40, Data: 0xf2 0 i2c-1 timeout [DrvSensorInit] Sensor initial fail! SNR pad 0 enable fail
1.3 Sensor初始化配置¶
芯片与Sensor通过I2C通讯上后,会通过handle->pCus_sensor_init
下发初始化寄存器表,初始化的寄存器表可以向Sensor厂商索要。驱动中的初始化表如下:
每个sensor都能够支持不同的MCLK,需要结合芯片支持的MCLK告知Sensor厂商给出相应MCLK下的初始化寄存器表进行下发。芯片对MCLK的支持情况可见drv_ms_cus_sensor.h
的CUS_MCLK_FREQ
2 Sensor驱动函数¶
头文件路径:drv_ms_cus_sensor.h
2.1 Sensor I2C API¶
参数 | 描述 | 定义 |
---|---|---|
handle->i2c_cfg.mode | I2C模式 | 见sensor_i2c_api.h的ISP_I2C_MODE |
handle->i2c_cfg.fmt | I2C格式,包含地址和数据位数 | 见sensor_i2c_api.h的ISP_I2C_FMT |
handle->i2c_cfg.address | I2C从地址,支持配置8bit的从地址 | 与Sensor规格书的I2C从地址一致 |
handle->i2c_cfg.speed | 最大的I2C速率 | 60000~320000 |
2.2 MCLK API¶
参数 | 描述 | 定义 |
---|---|---|
handle->mclk | MCLK | 见drv_ms_cus_sensor.h的CUS_MCLK_FREQ |
2.3 Sensor硬件信息定义¶
参数 | 描述 | 定义 |
---|---|---|
handle->sif_bus | Sensor的接口类型 | 见drv_ms_cus_sensor.h的CUS_SENIF_BUS |
handle->data_prec | Sensor输出的RAW数据位数 | 见drv_ms_cus_sensor.h的CUS_DATAPRECISION |
handle->bayer_id | Sensor Bayer RAW的起始ID | 见drv_ms_cus_sensor.h的CUS_SEN_BAYER |
handle->RGBIR_id | Sensor RGB IR的起始ID | 见drv_ms_cus_sensor.h的CUS_SEN_RGBIR |
handle->orient | Sensor的默认镜像翻转状态 | 见drv_ms_cus_sensor.h的CUS_CAMSENSOR_ORIT |
handle->interface_attr.attr_mipi.mipi_lane_num | MIPI Lane数 | SSD22X/SSD21X/SSC9211 最高支持2lane |
handle->interface_attr.attr_mipi.mipi_data_format | MIPI数据格式 | 见drv_ms_cus_sensor.h的CUS_SEN_INPUT_FORMAT |
handle->interface_attr.attr_mipi.mipi_yuv_order | 适用于MIPI,仅针对YUV Sensor | 见drv_ms_cus_sensor.h的CUS_SEN_YUV_ORDER |
2.4 信号极性API¶
参数 | 描述 | 定义 |
---|---|---|
handle->pwdn_POLARITY | 设置Sensor的PWDN脚极性 | 见drv_ms_cus_sensor.h的CUS_CLK_POL |
handle->reset_POLARITY | 设置Sensor的RESET脚极性 | 见drv_ms_cus_sensor.h的CUS_CLK_POL |
handle->VSYNC_POLARITY | 适用Parallel接口,设置VSYNC脚极性 | 见drv_ms_cus_sensor.h的CUS_CLK_POL |
handle->HSYNC_POLARITY | 适用Parallel接口,设置HSYNC脚极性 | 见drv_ms_cus_sensor.h的CUS_CLK_POL |
handle->PCLK_POLARITY | 适用Parallel接口,设置PCLK脚极性 | 见drv_ms_cus_sensor.h的CUS_CLK_POL |
2.5 Sensor控制API¶
参数 | 描述 |
---|---|
handle->pCus_sensor_release | Sensor释放函数 |
handle->pCus_sensor_init | Sensor初始化设置函数 |
handle->pCus_sensor_poweron | Sensor上电函数 |
handle->pCus_sensor_poweroff | Sensor下电函数 |
handle->pCus_sensor_GetSensorID | Sensor ID获取函数 |
handle->pCus_sensor_GetVideoResNum | Sensor分辨率个数获取函数 |
handle->pCus_sensor_GetVideoRes | Sensor支持分辨率获取函数 |
handle->pCus_sensor_GetCurVideoRes | Sensor当前分辨率获取函数 |
handle->pCus_sensor_SetVideoRes | Sensor设置分辨率函数 |
handle->pCus_sensor_GetOrien | Sensor镜像翻转状态获取函数 |
handle->pCus_sensor_SetOrien | Sensor镜像翻转设置函数 |
handle->pCus_sensor_GetFPS | Sensor帧率获取函数 |
handle->pCus_sensor_SetFPS | Sensor帧率设置函数 |
handle->pCus_sensor_SetPatternMode | Sensor测试图案设置函数 |
2.6 Sensor的AE控制API¶
参数 | 描述 |
---|---|
handle->pCus_sensor_AEStatusNotify | 在帧起始或末尾更新AE Gain、Shutter和帧率状态 |
handle->pCus_sensor_GetAEUSecs | 获取sensor shutter出图的曝光时间 |
handle->pCus_sensor_SetAEUSecs | 设置sensor shutter出图的曝光时间 |
handle->pCus_sensor_GetAEGain | 获取sensor的AE Gain |
handle->pCus_sensor_SetAEGain | 设置sensor的AE Gain |
handle->pCus_sensor_GetAEMinMaxGain | 获取sensor最小和最大的Gain |
handle->pCus_sensor_GetAEMinMaxUSecs | 获取sensor最小和最大的曝光时间 |
handle->pCus_sensor_GetShutterInfo | 获取sensor最小最大的行曝光和快门步长 |
2.7 Sensor接口操作API¶
参数 | 描述 |
---|---|
handle->PowerOff | 设置sensor硬件接口PowerDown脚拉高或拉低 |
handle->Reset | 设置sensor硬件接口RESET脚拉高或拉低 |
handle->MCLK | 设置芯片输出MCLK |
handle->SetIOPad | I/O总线模式 |
handle->SetCSI_Clk | 设置MIPI接口MAC CLK |
handle->SetCSI_Lane | 设置MIPI接口数据Lane数 |
handle->SetCSI_LongPacketType | 设置MIPI接口长包类型 |
3 芯片ISP与Sensor的关系¶
3.1 ISP->Sensor¶
3.2 Sensor->ISP¶
4 验证与调试¶
4.1 检查帧间隔¶
- Linux:
cat /sys/class/mstar/vif0/vif_ints
- RTOS:
vif_ints
== VIF CH-0 == Interval(ns) : 33337000 VREF_RISING : 109545 VREF_FALLING : 0 LINE_CNT_0 : 109545 LINE_CNT_1 : 109545
参数 | 说明 |
---|---|
Interval | 帧间隔,单位ns,表示frame start间隔时间,帧率=1000000000/Interval |
VREF_RISING | 帧开始上升沿计数 |
VREF_FALLING | 帧开始下降沿计数 |
LINE_CNT_0 | Line count中断触发次数,接收到图像总高度的50%就增加 |
LINE_CNT_1 | Line count中断触发次数,接收到图像总高度的100%就增加 |
通常情况下,单边上升沿采样并且LINE_CNT_1中断是关闭的,所以VREF_FALLING和LINE_CNT_1是0。一般来说VREF_RISING、LINE_CNT_0有在持续计数,并且有帧间隔的话,Sensor端的数据基本上没有问题。如果数据均为0,那么说明数据没有正常送到VIF,此时会有报Sensor Abnormal的Log,这时需要检查Sensor端数据是否正常,推荐MIPI Sensor使用non-continue mode的配置。 通过这个能够检查传输过来的高度是否满足,但是仅仅高度满足也是不行的,如果其中某一行少了一个像素点也会收不满。可以开启LINE_CNT_1的中断检查高度是否满足。
4.2 检查流状态¶
- Linux:
cat /sys/class/mstar/vif0/vif_info
- RTOS:
vif_info
== VIF CH-0 == INTF_MODE = 4 CH_EN: 1 SRC: MIPI0 INPUT_FMT: RGB PIX_FMT: 10 bits HDR_EN: 0 HDR_CH: VC0 CROP_EN: 1 CROP_START_X: 0 - 1079 CROP_START_Y: 0 - 1279 PIXEL_CNT: 0 LINE_CNT: 0 TOTAL_PIXEL_CNT: 1080 TOTAL_LINE_CNT: 1280 LINE_HIT_CNT0: 1024 LINE_HIT_CNT1: 1280
uvc配置下发后
== VIF CH-0 == INTF_MODE = 4 CH_EN: 1 SRC: MIPI0 INPUT_FMT: RGB PIX_FMT: 10 bits HDR_EN: 0 HDR_CH: VC0 CROP_EN: 1 CROP_START_X: 0 - 1079 CROP_START_Y: 0 - 1279 PIXEL_CNT: 1080 LINE_CNT: 1280 TOTAL_PIXEL_CNT: 1080 TOTAL_LINE_CNT: 1280 LINE_HIT_CNT0: 1024 LINE_HIT_CNT1: 1280
参数 | 说明 |
---|---|
INTF_MODE | 帧间隔,单位ns |
PIXEL_CNT | VIF收到一行的pixel数 |
LINE_CNT | VIF收到的行数 |
4.3 检查VIF模块状态¶
- Linux:
cat /proc/mi_modules/mi_vif/mi_vif0
- RTOS:
cat_proc mi_vif
-----------------------------------------Common info for mi_vif----------------------------------------- ChnNum EnChnNum PassNum InPortNum OutPortNum CollectSize 8 1 1 0 2 0 ----------------------CMDQ kickoff counter----------------------- DevId current_buf_size Peak_buf_size 0 0 0 each dev buf info: offset length used_flag task_name SS-RTOS # ------------------------------Common info formi_vif only dump enabled chn------------------------------ ChnId PassNum EnInPNum EnOutPNum MMAHeapName ChnId current_buf_size Peak_buf_size user_pid 0 5f1000 5f1000 -1 each chn buf info: offset length used_flag task_name 57000 1fb000 1 vif0-out0-0 252000 1fb000 1 vif0-out0-0 44e000 1fb000 1 vif0-out0-0 -------------------------Input port common info for mi_vif only dump enabled port--------------------- ChnId PassId PortId user_buf_quota UsrInjectQ_cnt BindInQ_cnt TotalPendingBuf_size usrLockedInjectCnt ChnId PassId PortId newPulseQ_cnt nextTodoPulseQ_cnt curWorkingQ_cnt workingTask_cnt lazzyRewindTask_cnt ChnId PassId PortId Enable bind_module_id bind_module_name bind_ChnId bind_PortId bind_Type bind_Param enable ChnId PassId PortId SrcFrmrate DstFrmrate GetFrame/Ms FPS FinishCnt RewindCnt ----------------------Output port common info for mi_vif only for enabled port--------------------- ChnId PassId PortId usrDepth BufCntQuota usrLockedCnt totalOutPortInUsed DrvBkRefFifoQ_cnt DrvBkRefFifoQ_size 0 0 0 0 6 0 3 0 0 ChnId PassId PortId UsrGetFifoQ_cnt UsrGetFifoQ_size UsrGetFifoQ_seqnum UsrGetFifoQ_discardnum 0 0 0 0 0 0 0 ChnId PassId PortId workingTask_cnt finishedTask_cnt 0 0 0 2 0 ChnId PassId PortId GetFrame/Ms FPS FinishCnt RewindCnt GetTotalCnt GetOkCnt 0 0 0 30/1008 29.76 804 0 806 806 ----------------------------------------BindPeerInputPortList--------------------------------------- ChnId PassId PortId Enable bind_module_id bind_module_name bind_ChnId bind_PortId bind_Type bind_Param enable 0 0 0 1 7 mi_vpe 0 0 1 0 1 ----------------------------------dump Dev Attr-------------------------------------------------- Dev Intf Work Clk Hdr IsrCnt AsyncCnt EnqCnt BarCnt CheckCnt DequCnt 0 MIPI RGB_FRAME 2 0 1615 2313 806 806 3116 804 -------------------------------------dump outport attr----------------------------------------------- Dev Chn pipe Port Cap_size Dest_size Sel Scan Fmt Rate LineCnt Atom MetaInfo OutCount FailCount Fps 0 0 1 0(0,0,1920,1080)(1920,1080) 3 0 RG_12BPP 0 1080 2 326 325 0 30 Dev Chn Port Recv_size Out_size SubOut_size ReadIdx WriteIdx DequeIdx FrameStartCnt FrameDoneCnt VbFail DropFrameCnt RingBufStatus 0 0 0 ( 0, 0) ( 239,1079) ( 0, 0) 5 7 5 327 325 0 0 (3,3,3,3,3,1,1,3) -----------------------------------------Common info for mi_vif----------------------------------------- ChnNum EnChnNum PassNum InPortNum OutPortNum CollectSize 8 0 1 0 2 0 ----------------------CMDQ kickoff counter----------------------- DevId current_buf_size Peak_buf_size 1 0 0 each dev buf info: offset length used_flag task_name ------------------------------Common info formi_vif only dump enabled chn------------------------------ ChnId PassNum EnInPNum EnOutPNum MMAHeapName -------------------------Input port common info for mi_vif only dump enabled port--------------------- ChnId PassId PortId user_buf_quota UsrInjectQ_cnt BindInQ_cnt TotalPendingBuf_size usrLockedInjectCnt ChnId PassId PortId newPulseQ_cnt nextTodoPulseQ_cnt curWorkingQ_cnt workingTask_cnt lazzyRewindTask_cnt ChnId PassId PortId Enable bind_module_id bind_module_name bind_ChnId bind_PortId bind_Type bind_Param enable ChnId PassId PortId SrcFrmrate DstFrmrate GetFrame/Ms FPS FinishCnt RewindCnt ----------------------Output port common info for mi_vif only for enabled port--------------------- ChnId PassId PortId usrDepth BufCntQuota usrLockedCnt totalOutPortInUsed DrvBkRefFifoQ_cnt DrvBkRefFifoQ_size ChnId PassId PortId UsrGetFifoQ_cnt UsrGetFifoQ_size UsrGetFifoQ_seqnum UsrGetFifoQ_discardnum ChnId PassId PortId workingTask_cnt finishedTask_cnt ChnId PassId PortId GetFrame/Ms FPS FinishCnt RewindCnt GetTotalCnt GetOkCnt ----------------------------------------BindPeerInputPortList--------------------------------------- ChnId PassId PortId Enable bind_module_id bind_module_name bind_ChnId bind_PortId bind_Type bind_Param enable ----------------------------------dump Dev Attr-------------------------------------------------- Dev Intf Work Clk Hdr IsrCnt AsyncCnt EnqCnt BarCnt CheckCnt DequCnt 0 MIPI RGB_FRAME 2 0 1621 2321 809 809 3127 807 -------------------------------------dump outport attr----------------------------------------------- Dev Chn pipe Port Cap_size Dest_size Sel Scan Fmt Rate LineCnt Atom MetaInfo OutCount FailCount Fps 0 0 1 0(0,0,1920,1080)(1920,1080) 3 0 RG_12BPP 0 1080 2 329 328 0 30 Dev Chn Port Recv_size Out_size SubOut_size ReadIdx WriteIdx DequeIdx FrameStartCnt FrameDoneCnt VbFail DropFrameCnt RingBufStatus 0 0 0 ( 0, 0) ( 239,1079) ( 0, 0) 0 2 0 329 328 0 0 (1,0,3,3,3,3,3,3)
一般来说FrameDoneCnt不为0,在持续增加并且DropFrameCnt为0,表示VIF接收Sensor数据完全是OK的