硬件

Imx294的硬件设计是参考HDC8245进行设计的,只是将原来与imx290的LVDS通信方式修改为了MIPI模式(Imx294只支持MIPI D-PHY 4Lane),其他硬件上与HDC8245保持一致。在硬件设计上特别是LVDS通信方式,需要注意同步信息的设计,有的sensor与平台可以进行信号的软同步,有的则不行,对此需要针对不同的sensor和平台进行相应的修改,不能一味的照搬。由于对硬件部分的不熟悉,此部分内容无法进行详细的介绍。在出图过程中,对于ISP来说需要了解当前的通信方式LVDS,MIPI以及对应的lane信息,另外I2C信息也是一个重要的信息(尤其是多路sensor)。在代码中具体反映在cmos.c中,具体参数如下图所示。

在多路sensor配置的时候,需要将每个sensor的I2C地址配置正确,如果配置错误将无法出图。此外,此处不同ViPipe对应的I2C,在pqtool工具中查看寄存器时,填写的i2cdev相对应。

在cmos.c文件中,cmos_get_sns_regs_info函数中的一些配置也与硬件有关,具体如下图所示。

驱动

在进行sensor预研过程中,由于平台都是老平台故在底层的支持上直接套用之前的东西,通过上层媒控和ISP来进行参数的调整。但不同的sensor其INCK由于不同的通信方式,需要不同的时钟频率。Imx294当前采用的通信方式为MIPI,其对应的时钟频率为6-27Mhz,而对于Hi3519平台来说,监控方面暂时只对接了imx226和imx290两款sensor,其中imx226的时钟频率固定为72Mhz,imx290的时钟频率固定为37.125Mhz。针对上述情况,在底层驱动中不能简单的套用HDC8245的驱动,需要修改sensor的时钟频率,使得sensor能有正常的时钟频率(现在的时钟频率为24Mhz,进行PLL分频技术后,能达到72Mhz)。另外对于设备的采集,需要根据分辨率来确定VI和ISP的频率,另外当MIPI和LVDS的通道超过4个时,需要重新设置采集的频率,计算的方式如下:

VI_Freq * Pix_Width = Lan_Num * MIPI_Freq

其中,VI_Freq为VI的工作时钟,Pix_Width为像素位宽,Lan_Num为传输的Lane个数。

如果VI的工作频率为250M,MIPI数据为RAW12,4lane传输为例进行说明:

MIPI_Freq = (250 * 12)/4 = 750,即当MIPI的数据传输速度大于750M时,将无法出图,此时需要增大VI的工作频率。另外VI和ISP的频率是同步的,在增大VI频率的同时,需要增大ISP的频率,另外受限于VPSS的频率,实际出图的帧率可能会低于采集的帧率。上述频率的设置都需要在小系统初始化的时候进行配置。一般来说涉及到的寄存器包括PERI_CRG16,PERI_CRG19,PERI_CRG21,另外3519存在两个MIPI控制器,需要注意MISC_CTRL0寄存器,各个寄存器说明,请参考《Hi3519V101 专业型HD IP Camera SoC用户指南》。为了保证ISP的正常出图,在ISP层进行时钟,ISP,VI,VPSS,MIPI等频率的设置,防止媒控初始化sensor和驱动未进行正确的时钟配置导致无法出图。在多个sensor出图时,需要注意分频复用时,各个sensor的频率是否都能满足当前的分辨率和帧率,需要根据实际情况调整各个时钟频率。

媒控

媒控与ISP在图像上存在着紧密的联系,ISP组件不能单独的进行运行,需要媒控对VI等进行参数配置来实现出图。故媒控方面需要根据不同的通信接口(LVDS,MIPI,SLVS-ES等)进行参数的配置,如lan的顺序,同步码,分辨率大小等。当前的Imx294的分辨率跟imx290的分辨率上有一定的差距,在无法修改设备的HID,PID等信息的情况下,需要媒控的同事根据MIPI的通信方式和分辨率给出对应的临时版本。另外,媒控在MIPI参数配置的时候会对sensor进行复位,注意一些SOC平台会出现共用复位信号的问题,导致出图后出现奇数或偶数片sensor出图失败。

ISP

对于一款新sensor的出图,ISP大部分情况需要修改大量的代码,包括param_patch.c, imx294_sensor_ctl.c, imx294_cmos.c,imx294_slave_pri_priv.h, product.c等文件的代码,其中由于平台为之前已有平台,故对product.c和param_patch.c这两个代码文件修改量较少,而与sensor相关性较强的代码文件需要根据sensor数据手册进行大量的修改。

Imx294_sensor_ctl.c

此文件的内容为sensor的启动序列和sensor的I2C或SPI的配置。对于启动序列及寄存器通信方式的配置需要参考数据手册中的配置顺序及数据,Imx294具体参考章节为Standby cancel sequence when using xxx。此次我们的SOC平台为Hi3519A其不支持SLVS-EC的方式,故只能采用CSI-2模式(即MIPI方式)。按照数据手册的介绍,从上电后的待机状态中启动需要的序列的顺序如下:

  1. 在上电序列完成后,设置如下寄存器

    • 1.1 将0x3033寄存器设置为0x30(XMSTA,MSTSLV两位设置为1h)。

    • 1.2 将0x303C寄存器设置为0x01(SYS_MODE 设置为1h)。

    • 1.3 PLL设置,根据驱动设置的不同时钟频率进行不同的PLL参数设置,具体设置如表3-1所示。

    • 1.4 取消待机,将寄存器0x3000设置为0x12(STANDBY=0h,STBLOGIC=1h,STBMIPI=0h, STBDV=1h)。

    • 1.5 释放PLL,将寄存器0x310B设置为0x00(STBPL_IF=0h, STBPL_AD =0h)。

    • 1.6 初始化通信

    • 1) 设置PLSTMG寄存器.

    • 2)设置Global Timing寄存器。

    • 1.7 根据不同的输出模式,设置相应的寄存器,Imx294对应的输出模式总共有15种,14种(17:9)和5种(4:3),其中模式1,1A,7和10都存在于上述两种显示模式中,具体的分辨率和最大帧率如下表3-2所示。

表3-1 CSI-2模式下 PLRD1-PLRD15的设置

寄存器数值
PLRD1 PLRD2 PLRD3 PLRD4 PLRD10 PLRD11 PLRD12 PLRD13 PLRD14 PLRD15
输入时钟频率(MHz) 6 0120 00 90 00 00 00 00 01 02 02
12 0120 01 90 01
18 00C0 01 60 01
24 0120 02 90 02

表3-2 输出模式列表

模式 分辨率比例 分辨率长 分辨率宽 输出数据长度 最大帧率
0 4:3 3704 2778 14 28.82
1 4:3 3704 2778 12 48.22
17:9 4096 2160 12 57.76
1A 4:3 3704 2778 12 41.83
17:9 4096 2160 12 54.37
1B 17:9 3840 2160 12 61.43
2 17:9 4096 2160 10 68.13
2A 17:9 4096 2160 10 67.63
3 17:9 2048 1080 14 88.84
4 17:9 2048 1080 12 88.84
5 17:9 2048 1080 12 103.32
6 17:9 2048 1080 10 120.61
7 4:3 1852 1388 10 190.19
17:9 2048 1080 10 241.22
8 17:9 1364 720 12 117.14
9 17:9 1364 720 12 351.43
10 4:3 1234 308 12 376.25
17:9 1364 720 12 461.54
11 17:9 1364 720 10 58.08
  1. 设置完成后,延迟10ms及以上的时间进行下面的寄存器设置

    • 2.1 将0x3000寄存器设置为0x02(STANDBY=0h,STBLOGIC=1h,STBMIPI=0h, STBDV=0h)。
    • 2.2 将0x353E寄存器设置为0x92(CLKDIVEN=2h,SYSCLKEN=0h)。
    • 2.3 将0x353E寄存器设置为0x9A(CLKDIVEN=2h, SYSCLKEN=1h)。
    • 2.4 将0x3000寄存器设置为0x00(STANDBY=0h,STBLOGIC=0h,STBMIPI=0h, STBDV=0h)。
  2. 设置完成后,延迟7ms及以上时间进行下面的寄存器设置

    • 3.1 将0x3033寄存器设置为0x20(XMSTA =0h)。
    • 3.2 将0x3017寄存器设置为0Xa8(SYNCDRV=0h),只有当使用XHS和XVS输出时才进行配置。
    • 按照上述的流程进行启动序列的设置,因为当前Imx294采用的是I2C的方式对寄存器进行设置,需要设置I2C的地址,数据长度和地址长度。对于I2C的地址,因为SLASEL引脚为高电平,又因为我们现在是对寄存器进行写操作,故配置的地址为0x34,地址长度为2,数据长度位1,这样我们完成了sensor启动序列的配置。

imx294_slave_pri_priv.h

此文件中包含了Imx294不同模式下的宏定义,部分如下:

1.曝光类寄存器地址

值得注意的是最后关于VMAX设定的寄存器,此寄存器的值关乎到帧率问题,一般都序列启动后,通过修改VMAX的值来改变帧率。SHR和SVR两个寄存器是用来控制曝光时间,PGC和DGain寄存器为控制增益,其中PGC为模拟增益DGain为数字增益。

2.模式枚举

由于Imx294支持的模式比较多,此处只是按照需求采用部分模式。

imx294_cmos.c

此文件是sensor与平台进行3A算法参数设置的接口文件,其中AF模块采用我司自研的算法,不存在与sensor寄存器的通信,AWB模块中,只涉及到黑电平的设置,而当前Imx294还处于出图阶段暂时无法获取准确的黑电平,故此处黑电平采用文档提供的标准黑电平值。所以整个cmos.c文件中曝光算法的参数设置是最为关键的,包括增益,曝光时间,帧率等等,需要根据sensor的差异进行修改的部分接口如下。

static HI_S32 cmos_get_ae_default(ISP_DEV IspDev,AE_SENSOR_DEFAULT_S *pstAeSnsDft)

static HI_VOID cmos_again_calc_table(ISP_DEV IspDev,HI_U32 *pu32AgainLin, HI_U32 *pu32AgainDb)

static HI_VOID cmos_dgain_calc_table(ISP_DEV IspDev,HI_U32 *pu32DgainLin, HI_U32 *pu32DgainDb)

static HI_VOID cmos_gains_update(ISP_DEV IspDev,HI_U32 u32Again, HI_U32 u32Dgain)

static HI_S32 cmos_set_image_mode(ISP_DEV IspDev,ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode)

static HI_U32 cmos_get_sns_regs_info(ISP_DEV IspDev,ISP_SNS_REGS_INFO_S *pstSnsRegsInfo)

static HI_VOID imx294_cmos_fps_set(ISP_DEV IspDev,HI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft)

static HI_VOID cmos_slow_framerate_set(VI_PIPE ViPipe, HI_U32 u32FullLines, AE_SENSOR_DEFAULT_S *pstAeSnsDft)

static HI_VOID cmos_inttime_update(VI_PIPE ViPipe, HI_U32 u32IntTime)

static HI_VOID cmos_get_inttime_max(VI_PIPE ViPipe, HI_U16 u16ManRatioEnable, HI_U32 *au32Ratio, HI_U32 *au32IntTimeMax, HI_U32 *au32IntTimeMin, HI_U32 *pu32LFMaxIntTime)

其中具体涉及到的参数如下:

曝光时间

不同的输出模式其曝光时间也不同,具体的计算公式如下:

在线性模式下,cmos_inttime_update函数更新曝光时间比较简单,只需要将曝光时间根据公式进行转换便可,但在WDR模式下需要对长短帧两个帧进行曝光,需要根据数据手册来进行设置参数。另外,cmos_get_inttime_max函数对出图有影响,通过对曝光实际的最大值和最小值,形成了内置的AERoute。我们在cmos.c文件中,添加AERoute结构体,具体如下图所示。

在这个结构体重第一列表示的是曝光行,中间三列为增益,最后一列为PIRIS。曝光行的填写可以参考VMAX值。

其中不同的模式下需要设置不同的number of clocks per intimal offset period,部分模式的具体设置如下:

增益

不同的sensor对应的模拟增益,数字增益的范围及曲线之间存在不同,其中Imx294的模拟增益最大值27dB,数字增益最大值为18dB(非连续,只可以设置为0,6,12,18dB这四个数值)。故设置增益范围时,需按照如下所示进行设置。

又因为Imx294的模拟增益计算公式如下

Gain[dB] = -20log{(2048-PGC[10:0])/2048}

从公式中我们可以看出模拟增益与PGC的关系是非线性的,越靠近27dB增益的变化幅度越大,在此我们创建了增益与PGC数值的对应关系表,代码中通过查表来计算当前的增益寄存器值。当前寄存器的数值范围为0-1957,如果全部换算成表的话,其数组大小为1957,且存在大量的冗余数值,故精简后,模拟增益数组如下:

根据上述模拟增益表,利用接口cmos_again_calc_table和cmos_gains_update将模拟增益填写到对应的sensor寄存器。

此处需要注意,如果采用上述缩内容的,那么在cmos_again_calc_table中需要修改其计算方式,因为在cmos_gains_update函数中,寄存器最终输入的值为整个增益表的下表。现我们如果对下标进行上述的缩小,那么后续在实际使用中,需要重新映射。实际最好的方法即将gain表大小与sensor的可填写值范围相当,对于数值的计算我们可以使用VS等软件进行小程序的开发来关于gain表的计算,另外需要注意的是,海思平台对于sensor来说其增益的计算方式不一定相同,以前接触的imx290,imx185等sensor,其增益变化为直线,即寄存器的数值的变化与增益成线性变化,但是imx294的寄存器值变化与增益不成线性,故需要一定的转换。

sensor输出模式

接口cmos_set_image_mode利用输入的参数中的分辨率大小和帧率来设置不同的输出模式,最终来跟启动序列进行挂钩。

帧率的控制

接口imx294_cmos_fps_set利用输入的参数帧率来设置不同的VMAX,在不重新启用序列的前提下,通过计算得到的VMAX值来动态的修改输出分辨率,此处要注意,某些分辨率是无法达到一定的帧率,详细情况参考sensor数据手册。在sony的数据手册中,有些sensor推荐是VMAX不变,通过修改HMAX来进行帧率的控制,但是海思在进行最大曝光行配置时,默认修改VMAX,这样当修改HMAX值后可能会出现无法出图的现象。

除了上述AE的函数外,还有一些函数地方需要注意

  • static HI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_REGS_INFO_S *pstSnsRegsInfo)

    此函数为设置各个寄存器地址的函数,此处的寄存器配置需要与AE中的寄存器地址相匹配,当匹配不正确时,可能导致无法出图,另外此处设置的寄存器在当前文件中必须进行配置,不然寄存器的值将被默认修改为0x00,导致出图异常。

  • g_aunImx294BusInfo

    此结构体为配置sensor跟MIPI控制器的关系,对于多sensor的设备,需要硬件的同事提供相应的对应关系,不然会出现个别sensor无法出图的情况。

  • AE Route

    需要对sensor进行添加,保证设备有一个合理的曝光曲线。

通过上述ISP代码的修改,完成新sensor出图前准备,最终编译生成ISP库文件,利用调试工具等将驱动,媒控,ISP库放入设备中进行出图调试。调试过程中,需要学会查看以下信息,包括MIPI,ISP,VPSS,VI,VENC等,关于各个信息的说明如下。

调试信息

MIPI信息

当ISP库运行到create正常,但是获取增益报错或者在PlatformCreateIspAfterVin函数中出错时,首先进行MIPI信息的查看,在串口或者10023端口下输入cat /proc/umap/mipi_rx(具体指令不同的平台间存在差异,详细查看文档)。

MIPI信息中我们所关注点包括当前的工作模式workmode(MIPI还是LVDS),datatype的数据格式是否正确,WDRMode是否开启WDR模式是否正确,这个参数需要注意宽动态模式是否正确,ImgX,ImgY,ImgW,ImgH分别为图像采集的坐标和宽高,MIPI LANE INOR中可以看出当前使用的通道数,Detect Info为检测到的宽高,宽高不正确请排查起始点,宽高,MIPI的lane数量等。如果这些配置正确,请通过寄存器或者找硬件同事量信号,排查sensor的时钟频率,不同的sensor需要不同的时钟,如果时钟正确,MIPI信号线上有信号,请让硬件同事排查下接受端时候有问题,或者媒控配置的MIPI控制器参数是否正确,如果MIPI信号线上无信号,请查看本身代码,特别是序列是否正确或者被修改,可以通过PQTool工具来进行查看。

ISP信息

在串口或者10023端口下输入cat /proc/umap/isp出现类似如下

在ISP信息中,在出图阶段,要保证图像中的AE,ABW模块,IntRat为当前的ISP系列下的帧率,如果出现异常请查阅cmos.c文档中的set_fps函数。