海思Hi3519v101 sensor配置解析

        新换了工作,用到海思Hi3519v101,最开始先和摄像头sensor打交道。正好之前一直没有深入研究这一块,利用这个机会随调试随做些记录,算做研发文档了。

        load3519v101是加载Hi3519v101mpp库和ko的脚本,里边也包含了摄像头的配置,现在先贴出部分代码,在其中深入分析imx274、imx274_mipi和imx290。

if [ ${SNS_TYPE0} != "NULL" ] ; then		
		case $SNS_TYPE0 in
        imx226)
            tmp=0x11;
            himm 0x12010040 0x11;           # sensor0 clk_en, 72MHz
			# SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
			#imx226: viu0:600M,isp0:600M, viu1:300M,isp1:300M
			himm 0x1201004c 0x00094c23;
			himm 0x12010054 0x00024041;
            spi0_4wire_pin_mux;
            insmod extdrv/hi_ssp_sony.ko;
            ;;
        imx274)
            tmp=0x11;
            himm 0x12010040 0x11;           # sensor0 clk_en, 72MHz
			# SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
			#imx274:viu0: 600M,isp0:300M, viu1:300M,isp1:300M
			himm 0x1201004c 0x00094c23;
			himm 0x12010054 0x0004041;
            spi0_4wire_pin_mux;
            insmod extdrv/hi_ssp_sony.ko;
            ;;
        imx274_mipi)
            tmp=0x14;
			# SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
			#	viu0:300M,isp0:300M, viu1:300M,isp1:300M
			himm 0x1201004c 0x00094c21;
			himm 0x12010054 0x0004041;
            himm 0x12010040 0x14;           # sensor0 clk_en, 24MHz
            i2c0_pin_mux;
            ;;       
        imx290)
            tmp=0x18;
			# SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
			#imx290:viu0:340M,isp0:214M, viu1:340M,isp1:214M
			himm 0x1201004c 0x00094c24;
			himm 0x12010054 0x0004;
            himm 0x12010040 0x18;           # sensor0 clk_en, 37.125MHz
            i2c0_pin_mux;
            ;;       
        ov4689)
            tmp=0x14;
			# SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
			#ov4689:	viu0:300M,isp0:300M, viu1:300M,isp1:300M
			himm 0x1201004c 0x00094c21;
			himm 0x12010054 0x0004041;
            himm 0x12010040 0x14;           # sensor0 clk_en, 24MHz
            i2c0_pin_mux;
            ;;
        os08a10)
            tmp=0x14;
			# SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
			#os08a10:	viu0: 600M, isp0:300M, viu1:300M,isp1:300M
			himm 0x1201004c 0x00094c23;
			himm 0x12010054 0x0004041;
            himm 0x12010040 0x14;           # sensor0 clk_en, 24MHz
            i2c0_pin_mux;
            ;;	                  
        bt1120)
			# SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
			#	viu0:300M,isp0:300M, viu1:300M,isp1:300M
			himm 0x1201004c 0x00094c21;
			himm 0x12010054 0x0004041;
            himm 0x113c6200 0x0;  #disable dehaze
            himm 0x113d1400 0x0;  #disable acm
            himm 0x113c5200 0x0;  #disable sharpen
            #himm 0x20670000 0x0;
            ;;
        *)
            echo "xxxx Invalid sensor type $SNS_TYPE0 xxxx"
            report_error;;
    esac
fi

        下边先来详细分析imx274:

        imx274)
            tmp=0x11;
            himm 0x12010040 0x11;           # sensor0 clk_en, 72MHz
            # SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
            #imx274:viu0: 600M,isp0:300M, viu1:300M,isp1:300M
            himm 0x1201004c 0x00094c23;
            himm 0x12010054 0x0004041;
            spi0_4wire_pin_mux;
            insmod extdrv/hi_ssp_sony.ko;
            ;;

        第1句程序tmp=0x11:

        笔者开始以为这句代码没有用处,因为第2句中直接用了0x11。但后来看到SNS_TYPE1时才知道这是给它用的,这是后话。

        第2句程序himm 0x12010040 0x11:

        这句话需要参考《Hi3519V101 专业型HD IP Camera SoC用户指南》,在108-110页(3-27~3-29)中,这3页说明的是PERI_CRG16。PERI_CRG16 为 Sensor 时钟配置寄存器。 我们只看写入1的项。

        bit0为1,代表sensor0_clksel 为0001,即Sensor0 时钟(芯片输出给 sensor 的参考时钟)选择72MHz。

        bit4为1,代表sensor0_clken为1,即Sensor0 时钟(芯片输出给 sensor 的参考时钟)门控选择时钟打开。

        实际上这句话的作用已经在后边有了英文注释,很准确。

        第3句程序himm 0x1201004c 0x00094c23:

        同样需要参考《Hi3519V101 专业型HD IP Camera SoC用户指南》,在113-114页(3-32~3-33)中,这2页说明的是PERI_CRG19。PERI_CRG19 为媒体 CBB 频率配置寄存器 1。 我们只看写入1的项。

        bit0、bit1为1,代表vi0_clksel 为011,即VI0 时钟选择600MHz。

        bit5为1,代表vpss_clksel 为001,即VPSS 时钟选择300MHz。

        bit10、bit11为1,代表vedu_clksel  为011,即VEDU 时钟选择594MHz。

        bit14为1,代表vgs_clksel 为010,即VGS 时钟选择500MHz。

        bit16为1,代表gdc_clksel 为001,即GDC 时钟选择475MHz。

        bit19为1,代表ive_clksel 为001,即IVE 时钟选择396MHz。

        第4句程序himm 0x12010054 0x0004041:

        同样参考《Hi3519V101 专业型HD IP Camera SoC用户指南》,在115-116页(3-34~3-35)中,这2页说明的是PERI_CRG21。PERI_CRG21 为媒体 CBB 频率配置寄存器 2。 我们只看写入1的项。

        bit0为1,代表vi1_clksel 为001,即VI1 时钟选择300MHz。

        bit6为1,代表isp1_clksel 为00001,即ISP1 时钟选择300MHz。

        bit14为1,代表isp0_clksel 为00001,即ISP0 时钟选择300MHz。

        第5句程序spi0_4wire_pin_mux:

        这是脚本中的一个函数,源码如下:

spi0_4wire_pin_mux()
{
    #pinmux
    himm 0x1204018c 0x1;  #SPI0_SCLK
    himm 0x12040190 0x1;  #SPI0_SD0
    himm 0x12040194 0x1;  #SPI0_SDI
    himm 0x12040198 0x1;  #SPI0_CSN
    
    #drive capability   
    himm 0x12040998 0x150;  #SPI0_SCLK
    himm 0x1204099c 0x160;  #SPI0_SD0
    himm 0x120409a0 0x160;  #SPI0_SDI
    himm 0x120409a4 0x160;  #SPI0_CSN
}

        依然一句一句解读:

        himm 0x1204018c 0x1;  #SPI0_SCLK

        这回就不是参考《Hi3519V101 专业型HD IP Camera SoC用户指南》了,需要参考《Hi3519V101_PINOUT_CN》,这是一个excel文件,在 00.hardware\chip\document_cn 路径下。

        参考《Hi3519V101_PINOUT_CN》中的 3.管脚复用寄存器,其中有这样一项:

muxctrl_reg99 SPI0_SCLK管脚复用寄存器。 0x1204018C 0 SPI0_SCLK管脚复用关系选择。
0 : GPIO12_4
1 : SPI0_SCLK
2 : I2C0_SCL
3 : SPI0_3WIRE_CLK

其它:reserved

        可以看到,当设置为1时,选择的是SPI0_SCLK,与注释一致。

        himm 0x12040190 0x1;  #SPI0_SD0

        路子同上。

muxctrl_reg100 SPI0_SDO管脚复用寄存器。 0x12040190 0 SPI0_SDO管脚复用关系选择。
0 : GPIO12_5
1 : SPI0_SDO
2 : I2C0_SDA
3 : SPI0_3WIRE_DATA

其它:reserved

         可以看到,当设置为1时,选择的是SPI0_SDO,与注释一致。

        himm 0x12040194 0x1;  #SPI0_SDI

muxctrl_reg101 SPI0_SDI管脚复用寄存器。 0x12040194 0 SPI0_SDI管脚复用关系选择。
0 : GPIO12_6
1 : SPI0_SDI

其它:reserved

        可以看到,当设置为1时,选择的是SPI0_SDI,与注释一致。 

        himm 0x12040198 0x1;  #SPI0_CSN

muxctrl_reg102 SPI0_CSN管脚复用寄存器。 0x12040198 0 SPI0_CSN管脚复用关系选择。
0 : GPIO12_7
1 : SPI0_CSN
3 : SPI0_3WIRE_CSN

其它:reserved

        可以看到,当设置为1时,选择的是SPI0_CSN,与注释一致。

        himm 0x12040998 0x150;  #SPI0_SCLK

        参考《Hi3519V101_PINOUT_CN》中的 3.管脚复用寄存器,其中有这样一项:

pad_ctrl_reg102 SPI0_SCLK管脚驱动能力寄存器。 0x12040998 0x00000170 reserved reserved reserved SPI0_SCLK管脚电平转换速率。
0 : 快沿
1 : 慢沿
SPI0_SCLK管脚驱动能力选择:
0000:IO6_档位8
0001:IO6_档位7
0010:IO6_档位6
0011:IO6_档位5
0100:IO6_档位4
0101:IO6_档位3
0110:IO6_档位2
0111:IO6_档位1
reserved

        bit7~4: 0101,SPI0_SCLK管脚驱动能力选择IO6_档位3。

        bit8: 1,SPI0_SCLK管脚电平转换速率选择慢沿。

        himm 0x1204099c 0x160;  #SPI0_SD0

pad_ctrl_reg103 SPI0_SDO管脚驱动能力寄存器。 0x1204099C 0x00000170 reserved reserved reserved SPI0_SDO管脚电平转换速率。
0 : 快沿
1 : 慢沿
SPI0_SDO管脚驱动能力选择:
0000:IO6_档位8
0001:IO6_档位7
0010:IO6_档位6
0011:IO6_档位5
0100:IO6_档位4
0101:IO6_档位3
0110:IO6_档位2
0111:IO6_档位1
reserved

        bit7~4: 0110,SPI0_SDO管脚驱动能力选择IO6_档位2。

        bit8: 1,SPI0_SDO管脚电平转换速率选择慢沿。

        himm 0x120409a0 0x160;  #SPI0_SDI

pad_ctrl_reg104 SPI0_SDI管脚驱动能力寄存器。 0x120409A0 0x00000170 reserved reserved reserved SPI0_SDI管脚电平转换速率。
0 : 快沿
1 : 慢沿
SPI0_SDI管脚驱动能力选择:
0000:IO6_档位8
0001:IO6_档位7
0010:IO6_档位6
0011:IO6_档位5
0100:IO6_档位4
0101:IO6_档位3
0110:IO6_档位2
0111:IO6_档位1
reserve

        bit7~4: 0110,SPI0_SDI管脚驱动能力选择IO6_档位2。

        bit8: 1,SPI0_SDI管脚电平转换速率选择慢沿。

        himm 0x120409a4 0x160;  #SPI0_CSN

pad_ctrl_reg105 SPI0_CSN管脚驱动能力寄存器。 0x120409A4 0x00000170 reserved reserved reserved SPI0_CSN管脚电平转换速率。
0 : 快沿
1 : 慢沿
SPI0_CSN管脚驱动能力选择:
0000:IO6_档位8
0001:IO6_档位7
0010:IO6_档位6
0011:IO6_档位5
0100:IO6_档位4
0101:IO6_档位3
0110:IO6_档位2
0111:IO6_档位1
reserved

        bit7~4: 0110,SPI0_CSN管脚驱动能力选择IO6_档位2。

        bit8: 1,SPI0_CSN管脚电平转换速率选择慢沿。

        第6句程序insmod extdrv/hi_ssp_sony.ko:

        这句很好理解,插入extdrv/下的hi_ssp_sony.ko模块。

        综合以上各语句,就能够完整地看出SNS_TYPE0为imx274时所做的全部配置了。先是配置各个时钟并使能,而后配置管脚复用以及配置驱动能力,最后插入对应模块。也能够得出结论:Hi3519和imx274通过SPI(Hi3519的SPI0)进行通讯;需要额外加载SONY的驱动才能正常通信。

=================================================================================================

        分析完了imx274,该分析imx274_mipi了。

        imx274_mipi)
            tmp=0x14;
            # SDK config:     IVE:396M,  GDC:475M,  VGS:500M,  VEDU:600M,   VPSS:300M 
            #    viu0:300M,isp0:300M, viu1:300M,isp1:300M
            himm 0x1201004c 0x00094c21;
            himm 0x12010054 0x0004041;
            himm 0x12010040 0x14;           # sensor0 clk_en, 24MHz
            i2c0_pin_mux;
            ;;       

        实际上和上边imx274非常类似。

        第1句程序tmp=0x14:

        笔者开始以为这句代码没有用处,因为第4句中直接用了0x14。但后来看到SNS_TYPE1时才知道这是给它用的,这是后话。

        

        第2句程序himm 0x1201004c 0x00094c21:

        这句话需要参考《Hi3519V101 专业型HD IP Camera SoC用户指南》,在113-114页(3-32~3-33)中,这2页说明的是PERI_CRG19。PERI_CRG19 为媒体 CBB 频率配置寄存器 1。 我们只看写入1的项。

        bit0为1,代表vi0_clksel 为001,即VI0 时钟选择300MHz。

        bit5为1,代表vpss_clksel 为001,即VPSS 时钟选择300MHz。

        bit10、bit11为1,代表vedu_clksel  为011,即VEDU 时钟选择594MHz。

        bit14为1,代表vgs_clksel 为010,即VGS 时钟选择500MHz。

        bit16为1,代表gdc_clksel 为001,即GDC 时钟选择475MHz。

        bit19为1,代表ive_clksel 为001,即IVE 时钟选择396MHz。

        第3句程序himm 0x12010054 0x0004041:

        同样参考《Hi3519V101 专业型HD IP Camera SoC用户指南》,在115-116页(3-34~3-35)中,这2页说明的是PERI_CRG21。PERI_CRG21 为媒体 CBB 频率配置寄存器 2。 我们只看写入1的项。

        bit0为1,代表vi1_clksel 为001,即VI1 时钟选择300MHz。

        bit6为1,代表isp1_clksel 为00001,即ISP1 时钟选择300MHz。

        bit14为1,代表isp0_clksel 为00001,即ISP0 时钟选择300MHz。

        

        第4句程序himm 0x12010040 0x14:

        同样参考《Hi3519V101 专业型HD IP Camera SoC用户指南》,在108-110页(3-27~3-29)中,这3页说明的是PERI_CRG16。PERI_CRG16 为 Sensor 时钟配置寄存器。 我们只看写入1的项。

        bit2为1,代表sensor0_clksel 为0100,即Sensor0 时钟(芯片输出给 sensor 的参考时钟)选择24MHz。

        bit4为1,代表sensor0_clken为1,即Sensor0 时钟(芯片输出给 sensor 的参考时钟)门控选择时钟打开。

        

        第5句程序i2c0_pin_mux:

        这是脚本中的一个函数,源码如下:

i2c0_pin_mux()
{
    #pinmux
    himm 0x12040190 0x2;  #I2C0_SDA
    himm 0x1204018c 0x2;  #I2C0_SCL
    
    #drive capability
    himm 0x1204099c 0x120; #I2C0_SDA
    himm 0x12040998 0x120; #I2C0_SCL    
}

        由于在上边介绍imx274的时候已经把寄存器贴出来了,并且进行了详细分析,因此这里就不再一一详细分析了,只做简单分析:

        himm 0x12040190 0x2;  #I2C0_SDA

        参考《Hi3519V101_PINOUT_CN》中的 3.管脚复用寄存器:

        当设置为2时,选择的是I2C0_SDA,与注释一致。

        himm 0x1204018c 0x2;  #I2C0_SCL

        当设置为2时,选择的是I2C0_SCL,与注释一致。

        himm 0x1204099c 0x120; #I2C0_SDA

        bit7~4: 0010,SPI0_SDO管脚驱动能力选择IO6_档位6。

        bit8: 1,SPI0_SDO管脚电平转换速率选择慢沿。

        himm 0x12040998 0x120; #I2C0_SCL

        bit7~4: 0101,SPI0_SCLK管脚驱动能力选择IO6_档位6。

        bit8: 1,SPI0_SCLK管脚电平转换速率选择慢沿。

        对于最后2项,有人会有疑问:都选择I2C了,怎么还是SPI0_SDO和SPI0_SCLK?其实笔者开始也有疑问,后来想明白了,应该是前边复用寄存器选择了i2c,之后这2个寄存器的功能就变了,不再是配置SPI0的驱动能力了,而是配置I2C0的,只是资料中的名字还是叫SPIXX。

        至此,imx274_mipi的配置就结束了。可以看到,imx274_mipi的配置语句比imx274的简单了一些,主要是因为4线制SPI要配置4个引脚,而I2C只需要配置2个引脚即可。也不需要加载对应的ko。

        综合以上各语句,就能够完整地看出SNS_TYPE0为imx274_mipi时所做的全部配置了。先是配置各个时钟并使能,而后配置管脚复用以及配置驱动能力。也能够得出结论:Hi3519和imx274_mipi通过I2C(Hi3519的I2C0)进行通讯;不需要额外加载SONY的驱动就可以正常通信。

=================================================================================================

        分析完了imx274和imx274_mipi,该分析imx290了,但由于实际项目中是将imx290作为后置摄像头,因此我把imx290放在SNS_TYPE1的代码中进行讲解。

if [ ${SNS_TYPE1} != "NULL" ] ; then	
	case $SNS_TYPE1 in       
        imx290)
            tmp1=0x1800;
            tmp2=$((tmp+tmp1));
            himm 0x12010040 $tmp2;           # sensor1 clk_en, 37.125MHz
            i2c1_pin_mux;
            ;;
        ov4689)
            tmp1=0x1400;
            tmp2=$((tmp+tmp1));
            himm 0x12010040 $tmp2;           # sensor1 clk_en, 24MHz
            i2c1_pin_mux;
            ;;
		os08a10)
            tmp1=0x1400;
            tmp2=$((tmp+tmp1));
            himm 0x12010040 $tmp2;           # sensor1 clk_en, 24MHz
            i2c1_pin_mux;
            ;;      
        bt1120)
            himm 0x114c6200 0x0;  #disable dehaze
            himm 0x114d1400 0x0;  #disable acm
            himm 0x114c5200 0x0;  #disable sharpen
            #himm 0x20670000 0x0;
            ;;
	    *)
            echo "xxxx Invalid sensor type $SNS_TYPE1 xxxx"
            report_error;;
    esac			
fi

        下边来详细分析imx290作为SNS_TYPE1的代码:

        imx290)
            tmp1=0x1800;
            tmp2=$((tmp+tmp1));
            himm 0x12010040 $tmp2;           # sensor1 clk_en, 37.125MHz
            i2c1_pin_mux;
            ;;

        第1句程序tmp1=0x1800:

        这句没什么好说的,一目了然。

        第2句程序tmp2=$((tmp+tmp1)):

        这句程序就是把tmp和tmp1的值相加,赋给tmp2。其中:tmp1在上1句中赋值,值为0x1800;tmp在imx274_mipi中的第1句赋值(前边也提到了),值为0x14。因此tmp2的值为0x14+0x1800=0x1814。

        这里多说一句,$(( )) 用来作整数运算的。

        第3句程序himm 0x12010040 $tmp2;           # sensor1 clk_en, 37.125MHz:

        这句话需要参考《Hi3519V101 专业型HD IP Camera SoC用户指南》,在108-110页(3-27~3-29)中,这3页说明的是PERI_CRG16。PERI_CRG16 为 Sensor 时钟配置寄存器。 我们只看写入1的项。

        bit0为1,代表sensor0_clksel 为0100,即Sensor0 时钟(芯片输出给 sensor 的参考时钟)选择24MHz。

        bit4为1,代表sensor0_clken为1,即Sensor0 时钟(芯片输出给 sensor 的参考时钟)门控选择时钟打开。

        到这里就能明白为何把值赋给tmp了,就是为了保留SNS_TYPE0的值,不会在设置SNS_TYPE1时被干扰到。

        bit11为1,代表sensor1_clksel 为1000,即Sensor1 时钟(芯片输出给 sensor 的参考时钟)选择37.125MHz。

        bit12为1,代表sensor1_clken为1,即Sensor0 时钟(芯片输出给 sensor 的参考时钟)门控选择时钟打开。  

        实际上这句话的作用已经在后边有了英文注释,很准确。 

        第4句程序i2c1_pin_mux:

        这是脚本中的一个函数,源码如下:

i2c1_pin_mux()
{
    #pinmux
    himm 0x1204001c 0x2;  #I2C1_SDA
    himm 0x12040018 0x2;  #I2C1_SCL
    
    #drive capability
    himm 0x1204081c 0x120;  #I2C1_SDA
    himm 0x12040818 0x120;  #I2C1_SCL
}

        

        依然一句一句解读:

        himm 0x1204001c 0x2;  #I2C1_SDA

        参考《Hi3519V101_PINOUT_CN》中的 3.管脚复用寄存器,其中有这样一项:

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/106766442