Linux MIPI CSI 開(kāi)發(fā)指南
1 前言
1.1 文檔簡(jiǎn)介
介紹 VIN(video input)驅(qū)動(dòng)配置,API 接口和上層使用方法。
1.2 目標(biāo)讀者
camera 驅(qū)動(dòng)開(kāi)發(fā)、維護(hù)人員和應(yīng)用開(kāi)發(fā)人員。
1.3 適用范圍
表 1-1: 適用產(chǎn)品列表
內(nèi)核版本 | 驅(qū)動(dòng)文件 |
---|---|
Linux-4.9 | drivers/media/platform/sunxi_vin/*.c |
Linux-5.4 | drivers/media/platform/sunxi_vin/*.c |
2 模塊介紹
2.1 模塊功能介紹
Video input 主要由接口部分(CSI/MIPI)和圖像處理單元(ISP/VIPP)組成;
CSI/MIPI 部分主要實(shí)現(xiàn)視頻數(shù)據(jù)的捕捉;
ISP 實(shí)現(xiàn) sensor raw data 數(shù)據(jù)的處理,包括 lens 補(bǔ)償、去壞點(diǎn)、gain、gamma、de-mosaic、de-noise、color matrix 等以及一些 3A 的統(tǒng)計(jì);
VIPP 能對(duì)將圖進(jìn)行縮小、和打水印處理。VIPP 支持 bayer raw data 經(jīng)過(guò) ISP 處理后再縮小,也支持對(duì)一般的 YUV 格式的 sensor 圖像直接縮小。
2.2 相關(guān)術(shù)語(yǔ)介紹
表 2-1: 軟件術(shù)語(yǔ)
相關(guān)術(shù)語(yǔ) | 解釋說(shuō)明 |
---|---|
ISP | Image Signal Processor 圖像信號(hào)處理 |
VIPP | Video Input Post Processor 圖像輸入后處理 |
MIPI | Mobile Industry Processor Interface 移動(dòng)工業(yè)處理接口 |
CCI | Camera Control Interface 攝像頭控制接口 |
TDM | Time division multiplexing ISP 時(shí)分復(fù)用 |
MCLK | Master clock(From AP to camera)攝像頭主時(shí)鐘 |
PCLK | Pixel clock(From camera to AP,Sampling clock for data-bus)像素時(shí)鐘 |
YUV | Color Presentation(Y for luminance,U&V for Chrominance)圖像數(shù)據(jù)格式 |
2.3 驅(qū)動(dòng)框架介紹
圖 2-1: 驅(qū)動(dòng)框圖
VIN 驅(qū)動(dòng)可以分為 Kernel 層、Video Input Framework、Device Driver 層。
2.3.1 Kernel 層
V4l2 Framework;
Linux 內(nèi)核視頻驅(qū)動(dòng)第二版(Video for Linux Two );
3) 適用于收音機(jī)、視頻編解碼、視頻捕獲以及視頻輸出設(shè)備驅(qū)動(dòng);
4) 提供/dev/videoX 節(jié)點(diǎn),應(yīng)用通過(guò)該節(jié)點(diǎn)進(jìn)行相應(yīng)視頻流和控制操作;
Media Device Framework;
Linux 多媒體設(shè)備框架;
7) 適用于管理設(shè)備拓?fù)浣Y(jié)構(gòu);
8) 提供/dev/mediaX 節(jié)點(diǎn),通過(guò)該節(jié)點(diǎn)應(yīng)用可以獲取媒體設(shè)備拓?fù)浣Y(jié)構(gòu),并能夠通過(guò) API 控制子設(shè)備間數(shù)據(jù)流向。
2.3.2 Video Input Framework 層
Video Control : 視頻命令處理(分辨率協(xié)商,數(shù)據(jù)格式處理,Buffer 管理等);
Runtime Handle : 運(yùn)行時(shí)管理(Pipeline 管理,系統(tǒng)資源管理,中斷調(diào)度等);
Event Process : 事件管理(如上層調(diào)用,中斷等事件的接收與分發(fā));
Config Handle : 配置管理(如硬件拓?fù)浣Y(jié)構(gòu),模組自適應(yīng)列表等)。
2.3.3 Device Driver 層
Camera Modules : 模組驅(qū)動(dòng)(圖像傳感器,對(duì)焦電機(jī),閃光燈等驅(qū)動(dòng));
Camera Interfac : 接口驅(qū)動(dòng)(MIPI、Sub-Lvds 、HiSpi、Bt656、Bt601、Bt1120、DC等);
Image Signal Processor : 圖像處理器驅(qū)動(dòng)(基本處理模塊驅(qū)動(dòng),3A 統(tǒng)計(jì)驅(qū)動(dòng));
Video Input Post Processor : 視頻輸入后處理(Scaler,OSD 等)。
2.4 模塊配置介紹
2.4.1 kernel menuconfig 配置
首先,進(jìn)入 Device Drivers,選擇 Multimedia support ,然后依次打開(kāi) Cameras/video grabbers support 、Media Controller support 和 SUNXI platform devices, 如下圖所示。
圖 2-2: Device Drivers 選項(xiàng)配置
其次,進(jìn)入 SUNXI platform devices,選擇 sunxi video input (camera csi/mipi isp vipp)driver 和 v4l2 new driver for SUNXI,如下圖所示。
圖 2-3: Device Drivers 選項(xiàng)配置
最后,sunxi video input (camera csi/mipi isp vipp)driver 目錄下的其他選項(xiàng)需要根據(jù)實(shí)際產(chǎn)品需求進(jìn)行開(kāi)關(guān),如:使用閃光燈、對(duì)焦馬達(dá)、打開(kāi) vin log、使用 IOMMU 如下圖所示。
圖 2-4: Device Drivers 選項(xiàng)配置
2.4.2 Device Tree 配置說(shuō)明
? 設(shè)備樹(shù)文件的配置是該 SoC 所有方案的通用配置,對(duì)于 ARM64 CPU 而言,設(shè)備樹(shù)的路徑為:kernel/{KERNEL_VERSION}/arch/arm64/boot/dts/sunxi/sun*.dtsi。
? 設(shè)備樹(shù)文件的配置是該 SoC 所有方案的通用配置,對(duì)于 ARM32 CPU 而言,設(shè)備樹(shù)的路徑為:kernel/{KERNEL_VERSION}/arch/arm/boot/dts/sun*.dtsi。
? 板級(jí)設(shè)備樹(shù) (board.dts) 路徑:
/device/config/chips/{IC}/configs/{BOARD}/KERNEL_VERSION/board.dts。
在 sun.dtsi 文件中,配置了該 SoC 的 CSI 控制器的通用配置信息,一般不建議修改,由 CSI 驅(qū)動(dòng)維護(hù)者維護(hù),如果需要修改配置請(qǐng)修改板級(jí)設(shè)備樹(shù) board.dts,板級(jí)設(shè)備樹(shù)里面的內(nèi)容會(huì)覆蓋sun.dtsi 對(duì)應(yīng)的信息。
? vind 配置
&vind0 {
vind0_clk = <336000000>;
vind0_isp = <300000000>;
status = "okay";
tdm0:tdm@0 {
work_mode = <0>;
};
isp00:isp@0 {
work_mode = <0>;
};
scaler00:scaler@0 {
work_mode = <0>;
};
scaler10:scaler@4 {
work_mode = <0>;
};
scaler20:scaler@8 {
work_mode = <0>;
};
scaler30:scaler@12 {
work_mode = <0>;
};
actuator0:actuator@0 {
device_type = "actuator0";
actuator0_name = "ad5820_act";
actuator0_slave = <0x18>;
actuator0_af_pwdn = <>;
actuator0_afvdd = "afvcc-csi";
actuator0_afvdd_vol = <2800000>;
status = "disabled";
};
flash0:flash@0 {
device_type = "flash0";
flash0_type = <2>;
flash0_en = <>;
flash0_mode = <>;
flash0_flvdd = "";
flash0_flvdd_vol = <>;
status = "disabled";
};
sensor0:sensor@0 {
device_type = "sensor0";
sensor0_mname = "gc2053_mipi";
sensor0_twi_cci_id = <1>;
sensor0_twi_addr = <0x6e>;
sensor0_mclk_id = <0>;
sensor0_pos = "rear";
sensor0_isp_used = <1>;
sensor0_fmt = <1>;
sensor0_stby_mode = <0>;
sensor0_vflip = <0>;
sensor0_hflip = <0>;
sensor0_iovdd-supply = ;
sensor0_iovdd_vol = <1800000>;
sensor0_avdd-supply = ;
sensor0_avdd_vol = <2800000>;
sensor0_dvdd-supply = ;
sensor0_dvdd_vol = <1200000>;
sensor0_power_en = <>;
sensor0_reset = <&pio PA 18 1 0 1 0>;
sensor0_pwdn = <&pio PA 19 1 0 1 0>;
sensor0_sm_hs = <>;
sensor0_sm_vs = <>;
flash_handle = <&flash0>;
act_handle = <&actuator0>;
status = "okay";
};
sensor1:sensor@1 {
device_type = "sensor1";
sensor1_mname = "imx386_mipi_2";
sensor1_twi_cci_id = <0>;
sensor1_twi_addr = <0x20>;
sensor1_mclk_id = <1>;
sensor1_pos = "front";
sensor1_isp_used = <1>;
sensor1_fmt = <1>;
sensor1_stby_mode = <0>;
sensor1_vflip = <0>;
sensor1_hflip = <0>;
sensor1_iovdd-supply = ;
sensor1_iovdd_vol = <1800000>;
sensor1_avdd-supply = ;
sensor1_avdd_vol = <2800000>;
sensor1_dvdd-supply = ;
sensor1_dvdd_vol = <1200000>;
sensor1_power_en = <>;
sensor1_reset = <&pio PA 20 1 0 1 0>;
sensor1_pwdn = <&pio PA 21 1 0 1 0>;
sensor1_sm_hs = <>;
sensor1_sm_vs = <>;
flash_handle = <>;
act_handle = <>;
status = "okay";
};
vinc00:vinc@0 {
vinc0_csi_sel = <0>;
vinc0_mipi_sel = <0>;
vinc0_isp_sel = <0>;
vinc0_isp_tx_ch = <0>;
vinc0_tdm_rx_sel = <0>;
vinc0_rear_sensor_sel = <0>;
vinc0_front_sensor_sel = <0>;
vinc0_sensor_list = <0>;
work_mode = <0x0>;
status = "okay";
};
vinc01:vinc@1 {
vinc1_csi_sel = <2>;
vinc1_mipi_sel = <0xff>;
vinc1_isp_sel = <1>;
vinc1_isp_tx_ch = <1>;
vinc1_tdm_rx_sel = <1>;
vinc1_rear_sensor_sel = <0>;
vinc1_front_sensor_sel = <0>;
vinc1_sensor_list = <0>;
status = "disabled";
};
vinc02:vinc@2 {
vinc2_csi_sel = <2>;
vinc2_mipi_sel = <0xff>;
vinc2_isp_sel = <2>;
vinc2_isp_tx_ch = <2>;
vinc2_tdm_rx_sel = <2>;
vinc2_rear_sensor_sel = <0>;
vinc2_front_sensor_sel = <0>;
vinc2_sensor_list = <0>;
status = "disabled";
};
vinc03:vinc@3 {
vinc3_csi_sel = <0>;
vinc3_mipi_sel = <0xff>;
vinc3_isp_sel = <0>;
vinc3_isp_tx_ch = <0>;
vinc3_tdm_rx_sel = <0>;
vinc3_rear_sensor_sel = <1>;
vinc3_front_sensor_sel = <1>;
vinc3_sensor_list = <0>;
status = "disabled";
};
…………
};
其中:
status 是 vin 驅(qū)動(dòng)的總開(kāi)關(guān),對(duì)應(yīng)的是 media 設(shè)備,使用 vin 時(shí)必須設(shè)為 okay;
vind0_clk 是 vin 模塊的時(shí)鐘,實(shí)際使用時(shí)可以根據(jù) sensor 的幀率和分辨率來(lái)設(shè)置;
vind0_isp 是 isp 模塊時(shí)鐘,實(shí)際使用時(shí)可以根據(jù) sensor 的幀率和分辨率來(lái)設(shè)置;
vind0_clk 表示 csi clk,計(jì)算公式:幀率 x (vts)x (hts)x 1(wdr 則為 2) / 8 / 1(雙 pixel則為 2) / 1000000,向上取整,單位為 MH;vind0_isp 表示 isp clk,計(jì)算公式:幀率 x 寬 x 高 x 1.2 / 1000000,向上取整,單位為 MH;其中有些 ic 是沒(méi)有 isp_clk,csi_clk 和isp_clk 都是設(shè)置在 vind0_clk。那么 vind0_clk 設(shè)置為 csi_clk 和 isp_clk 中最大的數(shù)值;
work_mode: 0:online mode 1:offline mode, 根據(jù)使用需求配置;
flash0_type: 0:FLASH_RELATING, 1:FLASH_EN_INDEPEND, 2:FLASH_POWER
flash0_en: flash enable gpio, type = 0 of 1
flash0_mode: flash mode gpio, type = 0 of 1
flash0_flvdd: flash module io power handle string, pmu power supply, type = 2
flash0_flvdd_vol: flash module io power voltage, pmu power supply, type = 2
status: 是否使用 flash, disable 代表關(guān),okay 代表開(kāi)
actuator0_name: vcm name
actuator0_slave: vcm iic slave address
actuator0_af_pwdn: vcm power down gpio
actuator0_afvdd: vcm power handle string, pmu power supply
actuator0_afvdd_vol: vcm power voltage, pmu power supply
status: vcm if used, disable 代表關(guān),okay 代表開(kāi)
device_type: sensor type sensor0_mname: sensor name
sensor0_twi_cci_id:sensor 所使用的 twi 或者 cci 的 id。
sensor0_twi_addr:sensor 的 twi 地址
sensor0_mclk_id:sensor 所使用的 mclk 的 id。
sensor0_pos:sensor 的位置,前置還是后置,主要用在平板上。
sensor0_isp_used: not use isp 1:use isp
sensor0_fmt: 0:yuv 1:bayer raw rgb
sensor0_stby_mode: not shut down power at standby 1:shut down power at standby
sensor0_vflip: flip in vertical direction 0:disable 1:enable
sensor0_hflip: flip in horizontal direction 0:disable 1:enable
sensor0_iovdd-supply: camera module io power handle string, pmu power supply
sensor0_iovdd_vol: camera module io power voltage, pmu power supply
sensor0_avdd-supply: camera module analog power handle string, pmu power supply
sensor0_avdd_vol: camera module analog power voltage, pmu power supply
sensor0_dvdd-supply: camera module core power handle string, pmu power supply
sensor0_dvdd_vol: camera module core power voltage, pmu power supply
sensor0_power_en: camera module power enable gpio
sensor0_reset: camera module reset gpio
sensor0_pwdn: camera module pwdn gpio sensor0_sm_hs: camera module sm_hs
gpio sensor0_sm_vs: camera module sm_vs gpio status: open or close sensor de
vice flash/actautor/sensor 節(jié)點(diǎn)用于對(duì)應(yīng)的外設(shè)的開(kāi)關(guān)和配置。這些節(jié)點(diǎn)的配置一般需要參
考對(duì)應(yīng)方案的原理圖和外設(shè)的 data sheet 來(lái)完成。
vinc0_csi_sel:表示該 pipeline 上 parser 的 id,必須配置,且為有效 id。
vinc0_mipi_sel:表示該 pipeline 上 mipi(sublvds/hispi)的 id,不使用時(shí)配置為 0xff。
vinc0_isp_sel:表示該 pipeline 上 isp 的 id,必須配置,當(dāng) isp 為空時(shí),這個(gè) isp 只是表示路由不做 isp 的效果處理。
vinc0_isp_tx_ch 表示該 pipeline 上 isp 的 ch,必須配置,默認(rèn)為 0。當(dāng) sensor 是 bt656 多通道或者 WDR 出 RAW 時(shí),該 ch 可以配置 0~3 的值。
vinc0_tdm_rx_sel: 表示該 pipeline 上 tdm rx 的 ch,必須配置,默認(rèn)為 0。當(dāng)不使用 tdm功能時(shí),配置為 0xff;
vinc0_rear_sensor_sel 表示該 pipeline 上使用的后置 sensor 的 id。
vinc0_front_sensor_sel 表示該 pipeline 上使用的前置 sensor 的 id。
vinc0_sensor_list 表示是否使用 sensor_list 來(lái)時(shí)適配不同的模組,1 表示使用,0 表示不使用。
work_mode: 0:online mode 1:offline mode, 根據(jù)使用需求配置;只有 vinc0/4/8/12 可以配置。
status:vipp 的使能開(kāi)關(guān),okay or disable。
2.5 源碼模塊結(jié)構(gòu)
驅(qū)動(dòng)路徑位于 drivers/media/platform/sunxi-vin 目錄。
sunxi-vin:.
├── Kconfig
├── Makefile
├── modules
│ ├── actuator
│ │ ├── actuator.c ;vcm driver的一般行為
│ │ ├── actuator.h ;vcm driver的頭文件
│ │ ├── ad5820_act.c ;具體vcm driver型號(hào)實(shí)現(xiàn)
│ │ ├── an41908a_act.c ;具體vcm driver型號(hào)實(shí)現(xiàn)
│ │ ├── dw9714_act.c ;具體vcm driver型號(hào)實(shí)現(xiàn)
│ │ ├── Makefile ;編譯文件
│ ├── flash
│ │ ├── flash.c ;led補(bǔ)光燈控制實(shí)現(xiàn)
│ │ ├── flash.h ;led補(bǔ)光燈驅(qū)動(dòng)頭文件
│ └── sensor
│ ├── ar0238.c ;具體的sensor驅(qū)動(dòng)
│ ├── camera_cfg.h ;camera ioctl擴(kuò)展命令頭文件
│ ├── camera.h ;camera公用結(jié)構(gòu)體頭文件
│ ├── gc030a_mipi.c ;具體的sensor驅(qū)動(dòng)
│ ├── gc0310_mipi.c ;具體的sensor驅(qū)動(dòng)
│ ├── gc5024_mipi.c ;具體的sensor驅(qū)動(dòng)
│ ├── imx179_mipi.c ;具體的sensor驅(qū)動(dòng)
│ ├── imx214.c ;具體的sensor驅(qū)動(dòng)
│ ├── imx219.c ;具體的sensor驅(qū)動(dòng)
│ ├── imx317_mipi.c ;具體的sensor驅(qū)動(dòng)
│ ├── Makefile ;驅(qū)動(dòng)的編譯文件
│ ├── nvp6134 ;具體的dvp sensor驅(qū)動(dòng)
│ │ ├── acp.c
│ │ ├── acp_firmup.c
│ │ ├── acp_firmup.h
│ │ ├── acp.h
│ │ ├── common.h
│ │ ├── csi_dev_nvp6134.c
│ │ ├── csi_dev_nvp6134.h
│ │ ├── eq.c
│ │ ├── eq_common.c
│ │ ├── eq_common.h
│ │ ├── eq.h
│ │ ├── eq_recovery.c
│ │ ├── eq_recovery.h
│ │ ├── Makefile
│ │ ├── nvp6134c.c ;具體的sensor驅(qū)動(dòng)實(shí)現(xiàn)
│ │ ├── type.h
│ │ ├── video.c
│ │ └── video.h
│ ├── nvp6158 ;具體的dvp sensor驅(qū)動(dòng)
│ │ ├── audio.c ;音頻部分實(shí)現(xiàn)
│ │ ├── audio.h ;音頻部分頭文件接口
│ │ ├── coax_protocol.c
│ │ ├── coax_protocol.h
│ │ ├── coax_table.h
│ │ ├── common.h
│ │ ├── Makefile
│ │ ├── modules.builtin
│ │ ├── modules.order
│ │ ├── motion.c
│ │ ├── motion.h
│ │ ├── nvp6158c.c ;具體的sensor驅(qū)動(dòng)實(shí)現(xiàn)
│ │ ├── nvp6158_drv.c
│ │ ├── nvp6158_drv.h
│ │ ├── nvp6168_eq_table.h
│ │ ├── video_auto_detect.c
│ │ ├── video_auto_detect.h
│ │ ├── video.c
│ │ ├── video_eq.c
│ │ ├── video_eq.h
│ │ ├── video_eq_table.h
│ │ ├── video.h
│ ├── rn6854m_mipi.c ;具體的sensor驅(qū)動(dòng)實(shí)現(xiàn)
│ ├── sensor-compat-ioctl32.c
│ ├── sensor_helper.c ;驅(qū)動(dòng)函數(shù)接口的實(shí)現(xiàn)
│ ├── sensor_helper.h ;驅(qū)動(dòng)函數(shù)接口的定義
├── modules.builtin
├── modules.order
├── platform
│ ├── platform_cfg.h ;vin平臺(tái)配置文件
│ ├── sun50iw10p1_vin_cfg.h ;不同平臺(tái)配置文件
│ ├── sun50iw3p1_vin_cfg.h ;不同平臺(tái)配置文件
│ ├── sun50iw6p1_vin_cfg.h ;不同平臺(tái)配置文件
│ ├── sun50iw9p1_vin_cfg.h ;不同平臺(tái)配置文件
│ ├── sun8iw12p1_vin_cfg.h ;不同平臺(tái)配置文件
│ ├── sun8iw15p1_vin_cfg.h ;不同平臺(tái)配置文件
│ ├── sun8iw16p1_vin_cfg.h ;不同平臺(tái)配置文件
│ └── sun8iw19p1_vin_cfg.h ;不同平臺(tái)配置文件
├── top_reg.c
├── top_reg.h
├── top_reg_i.h
├── top_reg.o
├── utility
│ ├── bsp_common.c
│ ├── bsp_common.h
│ ├── bsp_common.o
│ ├── cfg_op.c ;讀取ini文件的實(shí)現(xiàn)函數(shù)
│ ├── cfg_op.h ;讀取ini文件的實(shí)現(xiàn)函數(shù)
│ ├── config.c ;sensor電壓、通道選擇、i2c地址等信息讀取函數(shù)
│ ├── config.h ;sensor電壓、通道選擇、i2c地址等信息讀取函數(shù)頭文件
│ ├── vin_io.h ;vin模塊寄存器操作頭文件
│ ├── vin_os.c
│ ├── vin_os.h
│ ├── vin_supply.c
│ ├── vin_supply.h
├── vin.c
├── vin-cci
│ ├── bsp_cci.c ;底層cci bsp函數(shù)
│ ├── bsp_cci.h ;底層cci bsp函數(shù)頭文件
│ ├── cci_helper.c ;cci 幫助函數(shù),供sensor驅(qū)動(dòng)調(diào)用
│ ├── cci_helper.h ;cci 幫助函數(shù)頭文件
│ ├── csi_cci_reg.c ;cci硬件底層實(shí)現(xiàn)
│ ├── csi_cci_reg.h ;cci硬件底層實(shí)現(xiàn)頭文件
│ ├── csi_cci_reg_i.h ;cci 寄存器資源頭文件
│ ├── Kconfig
│ ├── sunxi_cci.c ;cci 平臺(tái)驅(qū)動(dòng)源文件
│ ├── sunxi_cci.h ;cci 平臺(tái)驅(qū)動(dòng)頭文件
├── vin-csi
│ ├── parser_reg.c ;CSI控制函數(shù)
│ ├── parser_reg.h ;CSI控制函數(shù)頭文件
│ ├── parser_reg_i.h ;CSI 寄存器值
│ ├── sunxi_csi.c ;csi 子模塊驅(qū)動(dòng)原文件
│ ├── sunxi_csi.h ;csi 子模塊驅(qū)動(dòng)頭文件
├── vin.h
├── vin-isp
│ ├── isp500
│ │ ├── isp500_reg_cfg.c
│ │ ├── isp500_reg_cfg.h
│ │ ├── isp500_reg_cfg.o
│ │ └── isp500_reg.h
│ ├── isp520
│ │ ├── isp520_reg_cfg.c
│ │ ├── isp520_reg_cfg.h
│ │ └── isp520_reg.h
│ ├── isp521
│ │ ├── isp521_reg_cfg.c
│ │ ├── isp521_reg_cfg.h
│ │ └── isp521_reg.h
│ ├── isp522
│ │ ├── isp522_reg_cfg.c
│ │ ├── isp522_reg_cfg.h
│ │ └── isp522_reg.h
│ ├── isp_default_tbl.h
│ ├── sunxi_isp.c
│ ├── sunxi_isp.h
│ └── sunxi_isp.o
├── vin-mipi
│ ├── bsp_mipi_csi.c ;底層mipi bsp函數(shù)
│ ├── bsp_mipi_csi.h ;底層mipi bsp函數(shù)頭文件
│ ├── bsp_mipi_csi_null.c ;底層mipi bsp空函數(shù)
│ ├── bsp_mipi_csi_v1.c ;底層mipi bsp函數(shù)--v1
│ ├── combo_common.h
│ ├── combo_csi
│ │ ├── combo_csi_reg.c
│ │ ├── combo_csi_reg.h
│ │ └── combo_csi_reg_i.h
│ ├── combo_rx
│ │ ├── combo_rx_reg.c
│ │ ├── combo_rx_reg.h
│ │ ├── combo_rx_reg_i.h
│ │ └── combo_rx_reg_null.c
│ ├── dphy
│ │ ├── dphy.h ;mipi dphy頭文件
│ │ ├── dphy_reg.c ;mipi dphy底層實(shí)現(xiàn)函數(shù)
│ │ ├── dphy_reg.h ;mipi dphy底層實(shí)現(xiàn)函數(shù)頭文件
│ │ └── dphy_reg_i.h ;mipi dphy 寄存器資源頭文件
│ ├── protocol
│ │ ├── protocol.h ;mipi協(xié)議層頭文件
│ │ ├── protocol_reg.c ;mipi協(xié)議層底層實(shí)現(xiàn)
│ │ ├── protocol_reg.h ;mipi協(xié)議層底層實(shí)現(xiàn)頭文件
│ │ └── protocol_reg_i.h
│ ├── protocol.h
│ ├── sunxi_mipi.c
│ ├── sunxi_mipi.h
├── vin-stat
│ ├── vin_h3a.c ;3A控制接口函數(shù)
│ ├── vin_h3a.h ;3A控制接口函數(shù)頭文件
├── vin-tdm
│ ├── tdm_reg.c ;TDM寄存器控制函數(shù)
│ ├── tdm_reg.h
│ ├── tdm_reg_i.h
│ ├── vin_tdm.c
│ └── vin_tdm.h
├── vin_test
│ ├── mplane_image
│ │ ├── csi_test_mplane.c ;camera抓圖測(cè)試用例
│ │ └── Makefile ;測(cè)試用例編譯文件
│ ├── sunxi_camera_v2.h
│ └── sunxi_display2.h
├── vin-video
│ ├── dma_reg.c ;csi dma寄存器控制函數(shù)
│ ├── dma_reg.h ;csi dma寄存器控制函數(shù)
│ ├── dma_reg_i.h ;csi dma 寄存器值定義頭文件
│ ├── vin_core.c ;vin模塊核心
│ ├── vin_core.h ;vin模塊核心頭文件
│ ├── vin_video.c ; 數(shù)據(jù)格式處理、pipe通道選擇、Buffer管理等函數(shù)
│ ├── vin_video.h ;數(shù)據(jù)格式處理、pipe通道選擇、Buffer管理等函數(shù)頭文件
└── vin-vipp
├── sunxi_scaler.c ;圖像壓縮處理函數(shù)
├── sunxi_scaler.h ;圖像壓縮處理函數(shù)頭文件
├── vipp_reg.c ;vipp寄存器控制函數(shù)
├── vipp_reg.h ;vipp寄存器控制函數(shù)頭文件
├── vipp_reg_i.h ;vipp寄存器具體描述頭文件
3 V4L2 接口描述
3.1 VIDIOC_QUERYCAP
3.1.1 Parameters
Capability of csi driver(struct v4l2_capability * capability)
struct v4l2_capability {
__u8 driver[16]; /* i.e. "bttv" */
__u8 card[32]; /* i.e. "Hauppauge WinTV" */
__u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
__u32 version; /* should use KERNEL_VERSION() */
__u32 capabilities; /* Device capabilities */
__u32 reserved[4];
};
3.1.2 Returns
Success:0; Fail: Failure Number
3.1.3 Description
獲取驅(qū)動(dòng)的名稱、版本、支持的 capabilities 等,如 V4L2_CAP_STREAMIN,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE 等。
3.2 VIDIOC_ENUM_INPUT
3.2.1 Parameters
input(struct v4l2_input *inp)
struct v4l2_input {
__u32 index; /* Which input */
__u8 name[32]; /* Label */
__u32 type; /* Type of input */
__u32 audioset; /* Associated audios (bitfield) */
__u32 tuner; /* Associated tuner */
v4l2_std_id std;
__u32 status;
__u32 capabilities;
__u32 reserved[3];
};
3.2.2 Returns
Success:0; Fail: Failure Number
3.2.3 Description
獲取驅(qū)動(dòng)支持的 input index。目前驅(qū)動(dòng)只支持 input index = 0 或 index = 1。
Index = 0 表示 primary csi device
Index = 1 表示 secondary csi device
應(yīng)用輸入 index 參數(shù),驅(qū)動(dòng)返回 type。對(duì)于 VIN 設(shè)備來(lái)說(shuō),type 為 V4L2_INPUT_TYPE_CAMERA。
3.3 VIDIOC_S_INPUT
3.3.1 Parameters
input(struct v4l2_input *inp)
The same as VIDIOC_ENUM_INPUT
3.3.2 Returns
Success:0; Fail: Failure Number
3.3.3 Description
通過(guò) inp.index 設(shè)置當(dāng)前要訪問(wèn)的 csi device 為 primary device 還是 secondary device。
Index = 0 (雙攝像頭配置中,一般對(duì)應(yīng)后置攝像頭。若只有一個(gè)攝像頭設(shè)備,則 index 固定為0)
Index = 1(雙攝像頭配置中,一般對(duì)應(yīng)前置攝像頭)
調(diào)用該接口后,實(shí)際上會(huì)對(duì) csi device 進(jìn)行初始化工作。
在 A133 平臺(tái):Index 在 video0、1 時(shí)固定要設(shè)為 0;在 video2、3 要設(shè)為 1。
3.4 VIDIOC_G_INPUT
3.4.1 Parameters
input(struct v4l2_input *inp)
The same as VIDIOC_ENUM_INPUT
3.4.2 Returns
Success:0; Fail: Failure Number
3.4.3 Description
獲取 inp.index,判斷當(dāng)前設(shè)置的 csi device 為 primary device 還是 secondary device。
Index = 0 (雙攝像頭配置中,一般對(duì)應(yīng)后置攝像頭。若只有一個(gè)攝像頭設(shè)備,則 index 固定為0)
Index = 1(雙攝像頭配置中,一般對(duì)應(yīng)前置攝像頭)
3.5 VIDIOC_S_PARM
3.5.1 Parameters
Parameter(struct v4l2_streamparm *parms)
struct v4l2_streamparm {
enum v4l2_buf_type type;
union {
struct v4l2_captureparm capture;
struct v4l2_outputparm output;
__u8 raw_data[200]; /* user-defined */
} parm;
};
struct v4l2_captureparm {
__u32 capability; /* Supported modes */
__u32 capturemode; /* Current mode */
struct v4l2_fract timeperframe; /* Time per frame in .1us units */
__u32 extendedmode; /* Driver-specific extensions */
__u32 readbuffers; /* # of buffers for read */
__u32 reserved[4];
};
3.5.2 Returns
Success:0; Fail: Failure Number
3.5.3 Description
CSI 作為輸入設(shè)備,只關(guān)注 parms.type 和 parms. capture。
應(yīng)用使用時(shí),parms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
其中通過(guò)設(shè)定 parms->capture.capturemode(V4L2_MODE_VIDEO 或 V4L2_MODE_IMAGE),
實(shí)現(xiàn)視頻或圖片的采集。通過(guò)設(shè)定 parms->capture.timeperframe,可以設(shè)置幀率。
3.6 VIDIOC_G_PARM
3.6.1 Parameters
Parameter(struct v4l2_streamparm *parms)
The same as VIDIOC_S_PARM
3.6.2 Returns
Success:0; Fail: Failure Number
3.6.3 Description
應(yīng)用使用時(shí),parms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
通過(guò) parms->capture.capturemode 返回當(dāng)前是 V4L2_MODE_VIDEO 或 V4L2_MODE_IMAGE;
通過(guò) parms->capture.timeperframe, 返回當(dāng)前設(shè)置的幀率。
3.7 VIDIOC_ENUM_FMT
3.7.1 Parameters
V4L2 format(struct v4l2_fmtdesc * fmtdesc) struct v4l2_fmtdesc { __u32 index; /* Format number */ enum v4l2_buf_type type; /* buffer type */ __u32 flags; __u8 description[32]; /* Description string */ __u32 pixelformat; /* Format fourcc */ __u32 reserved[4]; };
3.7.2 Returns
Success:0; Fail: Failure Number
3.7.3 Description
獲取驅(qū)動(dòng)支持的 V4L2 格式。
應(yīng)用輸入 type,index 參數(shù),驅(qū)動(dòng)返回 pixelformat 。對(duì)于 VIN 設(shè)備來(lái)說(shuō),type 為V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。
3.8 VIDIOC_TRY_FMT
3.8.1 Parameters
Video type, format and size(struct v4l2_format * fmt) struct v4l2_format { enum v4l2_buf_type type; union { struct v4l2_pix_format pix; struct v4l2_pix_format_mplane pix_mp; struct v4l2_window win; struct v4l2_vbi_format vbi; struct v4l2_sliced_vbi_format sliced; __u8 raw_data[200]; } fmt; }; struct v4l2_pix_format { __u32 width; __u32 height; __u32 pixelformat; enum v4l2_field field; __u32 bytesperline; /* for padding, zero if unused */ __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; /* private data, depends on pixelformat */ };
3.8.2 Returns
Success:0; Fail: Failure Number
3.8.3 Description
根據(jù)捕捉視頻的類型、格式和大小,判斷模式、格式等是否被驅(qū)動(dòng)支持。不會(huì)改變?nèi)魏斡布O(shè)置。
對(duì)于 VIN 設(shè)備,type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。使用 struct v4l2_pix_format_mplane 進(jìn)行參數(shù)傳遞。
應(yīng)用程序輸入 struct v4l2_pix_format_mplane 結(jié)構(gòu)體里面的 width、height、pixelformat、field 等參數(shù),驅(qū)動(dòng)返回最接近的 width、height;若 pixelformat、field 不支持,則默認(rèn)選擇驅(qū)動(dòng)支持的第一種格式。
3.9 VIDIOC_S_FMT
3.9.1 Parameters
Video type, format and size(struct v4l2_format * fmt) The same as VIDIOC_TRY_FMT
3.9.2 Returns
Success:0; Fail: Failure Number
3.9.3 Description
設(shè)置捕捉視頻的類型、格式和大小,設(shè)置之前會(huì)調(diào)用 VIDIOC_TRY_FMT。
對(duì)于 VIN 設(shè)備,type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。使用 struct v4l2_pix_format_mplane 進(jìn)行參數(shù)傳遞。應(yīng)用程序輸入 width、height、pixelformat、field 等,驅(qū)動(dòng)返回最接近的 width、height; 若 pixelformat、field 不支持,則默認(rèn)選擇驅(qū)動(dòng)支持的第一種格式。
應(yīng)用程序應(yīng)該以驅(qū)動(dòng)返回的 width、height、pixelformat、field 等作為后續(xù)使用傳遞的參數(shù)。對(duì)于 OSD 設(shè)備,type 為 V4L2_BUF_TYPE_VIDEO_OVERLAY。使用 struct v4l2_window進(jìn)行參數(shù)傳遞。
應(yīng)用程序輸入水印的個(gè)數(shù)、窗口位置和大小、bitmap 地址、bitmap 格式以及 global_alpha 等。驅(qū)動(dòng)保存這些參數(shù),并在 VIDIOC_OVERLAY 命令傳遞使能命令時(shí)生效。
3.10 VIDIOC_G_FMT
3.10.1 Parameters
Video type, format and size(struct v4l2_format * fmt) The same as VIDIOC_TRY_FMT
3.10.2 Returns
Success:0; Fail: Failure Number
3.10.3 Description
獲取捕捉視頻的 width、height、pixelformat、field、bytesperline、sizeimage 等參數(shù)。
3.11 VIDIOC_OVERLAY
3.11.1 Parameters
Overlay on/off(unsigned int i)
3.11.2 Returns
Success:0; Fail: Failure Number
3.11.3 Description
傳遞 1 表示使能,0 表示關(guān)閉。設(shè)置使能時(shí)會(huì)更新 osd 參數(shù),使之生效。
3.12 VIDIOC_REQBUFS
3.12.1 Parameters
Buffer type ,count and memory map type(struct v4l2_requestbuffers * req) struct v4l2_requestbuffers { __u32 count; enum v4l2_buf_type type; enum v4l2_memory memory; __u32 reserved[2]; };
3.12.2 Returns
Success:0; Fail: Failure Number
3.12.3 Description
v4l2_requestbuffers 結(jié)構(gòu)中定義了緩存的數(shù)量,驅(qū)動(dòng)會(huì)據(jù)此申請(qǐng)對(duì)應(yīng)數(shù)量的視頻緩存。多個(gè)緩存可以用于建立 FIFO,來(lái)提高視頻采集的效率。這些 buffer 通過(guò)內(nèi)核申請(qǐng),申請(qǐng)后需要通過(guò) mmap 方法,映射到 User 空間。
Count:定義需要申請(qǐng)的 video buffer 數(shù)量;
Type:對(duì)于 VIN 設(shè)備,為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Memory:目前支持 V4L2_MEMORY_MMAP、V4L2_MEMORY_USERPTR、V4L2_MEMORY_DMABUF 方式。
應(yīng)用程序傳遞上述三個(gè)參數(shù),驅(qū)動(dòng)會(huì)根據(jù) VIDIOC_S_FMT 設(shè)置的格式計(jì)算供需要 buffer 的大小,并返回 count 數(shù)量。
3.13 VIDIOC_QUERYBUF
3.13.1 Parameters
Buffer type ,index and memory map type(struct v4l2_buffer *buf) struct v4l2_buffer { __u32 index; enum v4l2_buf_type type; __u32 bytesused; __u32 flags; enum v4l2_field field; struct timeval timestamp; struct v4l2_timecode timecode; __u32 sequence; /* memory location */ enum v4l2_memory memory; union { __u32 offset; unsigned long userptr; struct v4l2_plane *planes; } m; __u32 length; __u32 input; __u32 reserved; };
3.13.2 Returns
Success:0; Fail: Failure Number
3.13.3 Description
通過(guò) struct v4l2_buffer 結(jié)構(gòu)體的 index,訪問(wèn)對(duì)應(yīng)序號(hào)的 buffer,獲取到對(duì)應(yīng) buffer 的緩存信息。主要利用 length 信息及 m.offset 信息來(lái)完成 mmap 操作。
3.14 VIDIOC_DQBUF
3.14.1 Parameters
Buffer type ,index and memory map type(struct v4l2_buffer *buf) struct v4l2_buffer is the same as VIDIOC_QUERYBUF
3.14.2 Returns
Success:0; Fail: Failure Number
3.14.3 Description
將 driver 已經(jīng)填充好數(shù)據(jù)的 buffer 出列,供應(yīng)用使用。
應(yīng)用程序根據(jù) index 來(lái)識(shí)別 buffer,此時(shí) m.offset 表示 buffer 對(duì)應(yīng)的物理地址。
3.15 VIDIOC_QBUF
3.15.1 Parameters
Buffer type ,index and memory map type(struct v4l2_buffer *buf)
3.15.2 Returns
Success:0; Fail: Failure Number
3.15.3 Description
將 User 空間已經(jīng)處理過(guò)的 buffer,重新入隊(duì),移交給 driver,等待填充數(shù)據(jù)。
應(yīng)用程序根據(jù) index 來(lái)識(shí)別 buffer。
3.16 VIDIOC_STREAMON
3.16.1 Parameters
Buffer type(enum v4l2_buf_type *type)
3.16.2 Returns
Success:0; Fail: Failure Number
3.16.3 Description
此處的 buffer type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。運(yùn)行此 IOCTL, 將 buffer 隊(duì)列中所有 buffer 入隊(duì),并開(kāi)啟 CSIC DMA 硬件中斷,每次中斷便表示完成一幀 buffer 數(shù)據(jù)的填入。
3.17 VIDIOC_STREAMOFF
3.17.1 Parameters
Buffer type(enum v4l2_buf_type *type)
3.17.2 Returns
Success:0; Fail: Failure Number
3.17.3 Description
此處的 buffer type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。運(yùn)行此 IOCTL,停止捕捉視頻,將 frame buffer 隊(duì)列清空,以及 video buffer 釋放。
3.18 VIDIOC_QUERYCTRL
3.18.1 Parameters
Control id and value(struct v4l2_queryctrl *qc) struct v4l2_queryctrl { __u32 id; enum v4l2_ctrl_type type; __u8 name[32]; /* Whatever */ __s32 minimum; /* Note signedness */ __s32 maximum; __s32 step; __s32 default_value; __u32 flags; __u32 reserved[2]; };
3.18.2 Returns
Success:0; Fail: Failure Number
3.18.3 Description
應(yīng)用程序通過(guò) id 參數(shù),驅(qū)動(dòng)返回需要調(diào)節(jié)參數(shù)的 name,minmum,maximum,default_value 以及步進(jìn) step。(由 v4l2 conctrols framework 完成)目前可能支持的 id 請(qǐng)參考 VIDIOC_S_CTRL。
3.19 VIDIOC_S_CTRL
3.19.1 Parameters
Control id and value(struct v4l2_queryctrl *qc) The same as VIDIOC_QUERYCTRL
3.19.2 Returns
Success:0; Fail: Failure Number
3.19.3 Description
應(yīng)用程序通過(guò) id,value 等參數(shù),對(duì) camera 驅(qū)動(dòng)對(duì)應(yīng)的參數(shù)進(jìn)行設(shè)置。
驅(qū)動(dòng)內(nèi)部會(huì)先調(diào)用 vidioc_queryctrl,判斷 id 是否支持,value 是否在 minimum 和 maximum 之間。(由 v4l2 conctrols framework 完成)目前可能支持的 id 和 value 參考附件。
3.20 VIDIOC_G_CTRL
3.20.1 Parameters
Control id and value(struct v4l2_queryctrl *qc) The same as VIDIOC_QUERYCTRL
3.20.2 Returns
Success:0; Fail: Failure Number
3.20.3 Description
應(yīng)用程序通過(guò) id,驅(qū)動(dòng)返回對(duì)應(yīng) id 當(dāng)前設(shè)置的 value。
3.21 VIDIOC_ENUM_FRAMESIZES
3.21.1 Parameters
index,type,format(struct v4l2_frmsizeenum) enum v4l2_frmsizetypes { V4L2_FRMSIZE_TYPE_DISCRETE = 1, V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, V4L2_FRMSIZE_TYPE_STEPWISE = 3, }; struct v4l2_frmsize_discrete { __u32 width; /* Frame width [pixel] */ __u32 height; /* Frame height [pixel] */ }; struct v4l2_frmsize_stepwise { __u32 min_width; /* Minimum frame width [pixel] */ __u32 max_width; /* Maximum frame width [pixel] */ __u32 step_width; /* Frame width step size [pixel] */ __u32 min_height; /* Minimum frame height [pixel] */ __u32 max_height; /* Maximum frame height [pixel] */ __u32 step_height; /* Frame height step size [pixel] */ }; struct v4l2_frmsizeenum { __u32 index; /* Frame size number */ __u32 pixel_format; /* Pixel format */ __u32 type; /* Frame size type the device supports. */ union { /* Frame size */ struct v4l2_frmsize_discrete discrete; struct v4l2_frmsize_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ };
3.21.2 Returns
Success:0; Fail: Failure Number
3.21.3 Description
根據(jù)應(yīng)用傳進(jìn)來(lái)的 index,pixel_format,驅(qū)動(dòng)返回 type,并根據(jù) type 填寫 discrete 或 step-wise 的值。Discrete 表示分辨率固定的值;stepwise 表示分辨率有最小值和最大值,并根據(jù)step 遞增。上層根據(jù)返回的 type,做對(duì)應(yīng)不同的操作。
3.22 VIDIOC_ENUM_FRAMEINTERVALS
3.22.1 Parameters
Index,format,size,type(struct v4l2_frmivalenum) enum v4l2_frmivaltypes { V4L2_FRMIVAL_TYPE_DISCRETE = 1, V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, V4L2_FRMIVAL_TYPE_STEPWISE = 3, }; struct v4l2_frmival_stepwise { struct v4l2_fract min; /* Minimum frame interval [s] */ struct v4l2_fract max; /* Maximum frame interval [s] */ struct v4l2_fract step; /* Frame interval step size [s] */ }; struct v4l2_frmivalenum { __u32 index; /* Frame format index */ __u32 pixel_format; /* Pixel format */ __u32 width; /* Frame width */ __u32 height; /* Frame height */ __u32 type; /* Frame interval type the device supports. */ union { /* Frame interval */ struct v4l2_fract discrete; struct v4l2_frmival_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ };
3.22.2 Returns
Success:0; Fail: Failure Number
3.22.3 Description
應(yīng)用程序通過(guò) pixel_format、width、height、驅(qū)動(dòng)返回 type,并根據(jù) type 填寫
V4L2_FRMIVAL_TYPE_DISCRETE、V4L2_FRMIVAL_TYPE_CONTINUOUS 或V4L2_FRMIVAL_TYPE_STEPWISE。Discrete 表示支持單一的幀率;stepwise 表示支持步進(jìn)的幀率。
3.23 VIDIOC_ISP_EXIF_REQ
作用: 得到當(dāng)前照片的 EXIF 信息,填寫到相應(yīng)的編碼域中。目的:對(duì)于 raw sensor 盡量填寫正規(guī)的 EXIF 信息,yuv sensor 該 IOCTRL 也可以使用,不過(guò)驅(qū)動(dòng)中填寫的也是固定值。相關(guān)參數(shù):
struct v4l2_fract { __u32 numerator; __u32 denominator; }; struct isp_exif_attribute { struct v4l2_fract exposure_time; struct v4l2_fract shutter_speed; __u32 aperture; __u32 focal_length; __s32 exposure_bias; __u32 iso_speed; __u32 flash_fire; __u32 brightness; }; struct v4l2_fract exposure_time; 曝光時(shí)間:分?jǐn)?shù)類型,例如numerator = 1,denominator = 200,則表示1/200秒的曝光時(shí)間。 struct v4l2_fract shutter_speed; 快門速度:分?jǐn)?shù)類型,例如numerator = 1,denominator = 200,則表示1/200秒的快門速度。(實(shí)際上和曝光時(shí)間數(shù)值相同) __u32 aperture; 光圈大?。篎Number,例如aperture = 22,則表示,光圈大小為2.2,即FNumber = 22/10; __u32 focal_length; 焦距:例如focal_length = 1400,則表示焦距為14mm,即FocalLength = 1400/100( mm); __s32 exposure_bias; 曝光補(bǔ)償:范圍 -4~4 __u32 iso_speed; 感光速度:50~3200 __u32 flash_fire; 閃光燈是否開(kāi)啟:flash_fire = 1 表示閃光燈開(kāi)啟,flash_fire = 0 表示閃光燈未開(kāi)啟。 __u32 brightness; 圖像亮度:0~255. 使用示例: int V4L2CameraDevice::getExifInfo(struct isp_exif_attribute *exif_attri) { int ret = -1; if (mCameraFd == NULL) { return 0xFF000000; } ret = ioctl(mCameraFd, VIDIOC_ISP_EXIF_REQ, exif_attri); return ret; }
4 模塊使用范例
4.1 測(cè)試 demo
模塊使用的 demo 的代碼位于 drivers/media/platform/sunxi-vin/vin_test/mplane_image;此目錄下可以直接 make 生成 demo;把 demo 推到機(jī)器里面執(zhí)行便可以獲取指定 video 節(jié)點(diǎn)的圖像。推薦在 pc 上創(chuàng)建 bat 批處理文件,使用 adb 命令完成一系列抓圖的動(dòng)作,bat 內(nèi)容參考如下,不同機(jī)器請(qǐng)注意修改 push 進(jìn)去的路徑:
del .result*.bin adb root adb remount adb shell "mkdir /vendor/extsd/" adb shell "mkdir /vendor/extsd/result" adb shell rm /vendor/extsd/result/*.bin adb push demo路徑csi_test_mplane /vendor/extsd/csi_test1 adb shell chmod 777 /vendor/extsd/csi_test1 adb shell "cd /vendor/extsd/ && ./csi_test1 0 0 1920 1080 ./result 1 20000 60 0" adb shell ls /vendor/extsd/result adb pull /vendor/extsd/result pause
最后會(huì)在 bat 指令的文件夾生成 result 文件夾里面保存二進(jìn)制的圖像數(shù)據(jù) *.bin 文件;可用 RawViewer 等軟件查看圖像數(shù)據(jù)。demo 參數(shù)說(shuō)明:0 0 1920 1080 ./result 1 20000 60 0,分別表示 video0,set_input index0,目標(biāo)分辨率寬,目標(biāo)分辨率高,bin 文件保存路徑、圖像格式(如 NV21,具體含義可以看 demo 代碼的 s_fmt 參數(shù))、采集幀數(shù)(幀數(shù)大于 10000 即為常開(kāi)節(jié)點(diǎn))、目標(biāo)幀率、和是否開(kāi)啟 wdr。
4.2 調(diào)用流程
圖 4-1: CSI 調(diào)用流程
5 FAQ
5.1 調(diào)試方法
5.1.1 調(diào)試節(jié)點(diǎn)
圖 5-1: vi 節(jié)點(diǎn)
當(dāng)系統(tǒng)打開(kāi) DEBUG_FS 編譯宏時(shí),可以 cat /sys/kernel/debug/mpp/vi 查看;否則可以
cat /sys/devices/platform/soc@2900000/2000800.vind/vi。
vi 節(jié)點(diǎn)保存的是當(dāng)前或上一次工作(當(dāng)前沒(méi)有工作)的狀態(tài)。下面對(duì) vi 節(jié)點(diǎn)的關(guān)鍵信息進(jìn)行說(shuō)明。
CSI_TOP、CSI_ISP 分別是對(duì)應(yīng) CSI、和 ISP 的工作頻率;input 一行表示 CSI 接收到的圖片尺寸,fmt 表示輸入數(shù)據(jù)的格式;
output 表示 CSI 出尺寸,如果使用了縮放或者裁剪,那么輸入輸出尺寸會(huì)不一致,fmt 表示數(shù)據(jù)的輸出格式;
最后一行分別表示平均幀間隔、最大幀間隔、最小幀間隔,可以計(jì)算得出幀率,調(diào)試幀率時(shí)可以參考。
5.1.2 settle time
方式一:修改對(duì)應(yīng) sensor 驅(qū)動(dòng)中的 sensor_probe 函數(shù),可以添加或修改 info->time_hs 的值即可。
圖 5-2: info->time_hs
方式二:通過(guò) mipi 子設(shè)備的 settle_time 節(jié)點(diǎn)在線進(jìn)行修改,settle_time 節(jié)點(diǎn)路徑:/sys/devices/platform/soc/5800800.vind/5810100.mipi。
進(jìn)入節(jié)點(diǎn)路徑后,可以看到當(dāng)前目錄下存在 settle_time 節(jié)點(diǎn):
圖 5-3: settle time 節(jié)點(diǎn)
可以通過(guò) cat、echo 命令,對(duì) settle_time 節(jié)點(diǎn)進(jìn)行讀寫操作:
圖 5-4: settle time 節(jié)點(diǎn)讀寫
調(diào)整策略:settle time 的值慢慢增大調(diào)整,調(diào)大直到不能出圖,再取一個(gè)略低于最大值的數(shù)值即可。調(diào)整范圍:0x00-0xff。
5.1.3 信號(hào)狀態(tài)
介紹如何觀測(cè) SOC 主控的接收數(shù)據(jù)的信號(hào)狀態(tài),分別對(duì) MIPI 和并口做出說(shuō)明。
5.1.3.1 MIPI
MIPI 傳輸模式有兩種:
LP(Low-Power)模式:用于傳輸控制信號(hào),最高速率 10 MHz。
HS(High-Speed)模式:用于高速傳輸數(shù)據(jù),以 MIPI DPHY V1.1 版本為例,速率范圍 [80Mbps - 1.5Gbps] per Lane。
可以通過(guò)查看 user manual MIPI PHY 部分寄存器,觀測(cè) SOC 識(shí)別到的 clock lane 和 data lane 的 LP、HS 狀態(tài)。
5.1.3.2 并口
對(duì)于并口接口的 sensor,可以查看 user manual CSI PARSER 部分的 parser signal 寄存器,觀測(cè) sensor 端 PCLK、DATA 的信號(hào)狀態(tài)。以此判斷 parser 是否有識(shí)別到 sensor 端發(fā)送的數(shù)據(jù)。
5.2 常見(jiàn)問(wèn)題
5.2.1 I2C 不通
如下圖打?。?/p>
圖 5-5: i2c 不通
【分析步驟一】:確認(rèn)供電、MCLK、i2c 上拉等外圍電路信號(hào)是否正常。使用萬(wàn)用表測(cè)量板子上AVDD、DVDD、IOVDD 供電電壓、MCLK 頻率、幅度、RESET、PWDN 的電平是否符合要求。
【分析步驟二】:確認(rèn) i2c 地址,TWI 通道是否和原理圖一致。
【分析步驟三】:以上都正常就用示波器或者邏輯分析儀測(cè)量分析主控發(fā)出 i2c 波形是否正確、有無(wú)回應(yīng);最后可以考慮 sensor 損壞或者接口錯(cuò)位等問(wèn)題。
5.2.2 sensor 不出圖
【分析步驟一】:確認(rèn) chip id 和 datasheet 上一致。
在對(duì)應(yīng) sensor 驅(qū)動(dòng)的 sensor_detect 函數(shù)中讀 chip id 寄存器,這一步也能檢驗(yàn) i2c 的讀寫是否正確。
【分析步驟二】:確認(rèn)配置已經(jīng)配置到 sensor 里。
可以把寫進(jìn)去的寄存器讀出來(lái)和寫入值對(duì)比是否一致。
【分析步驟三】:確認(rèn)配置正確并且 sensor 已經(jīng)輸出圖像。
和原廠確認(rèn)寄存器配置、用示波器測(cè)量 sensor 端的 mipi 數(shù)據(jù) lane 和時(shí)鐘 lane 波形,分析是否正在發(fā)送數(shù)據(jù)。
【分析步驟四】:確認(rèn) SOC 是否接收到 sensor 數(shù)據(jù)。
mipi 的 clock lane 存在兩種工作模式,一種是連續(xù)時(shí)鐘模式,傳輸過(guò)程不會(huì)切換 LP 狀態(tài);另一種是非連續(xù)時(shí)鐘信號(hào)模式,每傳輸完一幀圖像數(shù)據(jù),幀 blanking 時(shí)將會(huì)切換為 LP 狀態(tài)。目前大部分 MIPI sensor 一般都是非連續(xù)時(shí)鐘模式。
如果 sensor 是連續(xù)時(shí)鐘模式,要保證 MIPI 在 sensor 之前初始化,需要在 sensor 驅(qū)動(dòng) sensor_probe() 中配置 info->stream_seq = MIPI_BEFORE_SENSOR;
如果 sensor 是非連續(xù)時(shí)鐘模式,可以通過(guò)判斷 SOC 識(shí)別到的 LP、HS 模式狀態(tài)是否在不斷切換,來(lái)間接判斷 SOC 的 MIPI 的接收狀態(tài)。
查看 user manual MIPI PHY 部分寄存器,觀測(cè) clock lane 和 data lane 的 LP、HS 狀態(tài)是否有在不斷切換,有則說(shuō)明 MIPI 已經(jīng)接收到了 sensor 發(fā)送的數(shù)據(jù)。如果沒(méi)有切換則說(shuō)明 MIPI 沒(méi)有正確接收 sensor 數(shù)據(jù)。此時(shí)應(yīng)該檢查 MIPI 相關(guān)配置是否正確。
【分析步驟五】:嘗試修改 settle time。
如果可以確定 sensor 已經(jīng)在正確發(fā)送數(shù)據(jù),只是 MIPI 這邊一直接收不到導(dǎo)致無(wú)法出圖,可以嘗試修改 settle time(參考調(diào)試方法章節(jié))。
5.2.3 已出圖但畫面是綠色或者粉紅色
一般是 YUYV 順序反了,可以修改 sensor 驅(qū)動(dòng)中 sensor_formats 結(jié)構(gòu)體的 mbus_code 參數(shù),修改 YUV 順序即可。
5.2.4 I2c 已通,但是讀所有 sensor 寄存器值都為 0
【分析步驟一】檢查 i2c 通訊 addr 和 data 的位寬。
檢查 sensor 驅(qū)動(dòng)中 cci_drv 結(jié)構(gòu)體中定義的值是否符合 datasheet 要求。
【分析步驟二】檢查 i2c 通訊數(shù)據(jù)大小端是否不一致。
可以在讀 sensor id 時(shí)把地址高低位相反來(lái)快速驗(yàn)證一下。
5.2.5 畫面旋轉(zhuǎn) 180 度
可以修改 board.dts 里面的 hflip 和 vflip 來(lái)解決,如果畫面和人眼成 90 度的話,只能通過(guò)修改 sensor 配置來(lái)解決(只有部分 sensor 支持)。
5.2.6 沒(méi)有 video 節(jié)點(diǎn)
【問(wèn)題解析】沒(méi)有加載 ko 或者 ko 加載失敗。
【分析步驟一】檢查模塊加載順序是否正確。
lsmod 看一下模塊是否加載正確,如果報(bào)的錯(cuò)誤是 [VIN_ERR]registering gc2355_mipi, No such device! 則表明 sensor 模塊 gc2355_mipi 沒(méi)有加載。
【分析步驟二】檢查 board.dts 文件配置是否配置了 vind0,且 status 為 okay。
【分析步驟三】如果是加載失敗檢查加載失敗的原始是 i2c 不通還是沒(méi)有 ko。
i2c 不通參考前面的分析,沒(méi)有 ko 請(qǐng)檢查是否有對(duì)應(yīng)的驅(qū)動(dòng)并且在 Makefile 中使能了編譯。
-
Linux
+關(guān)注
關(guān)注
87文章
11342瀏覽量
210308 -
MIPI
+關(guān)注
關(guān)注
11文章
312瀏覽量
48752 -
CSI
+關(guān)注
關(guān)注
1文章
36瀏覽量
51031 -
編譯
+關(guān)注
關(guān)注
0文章
661瀏覽量
33019
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論