名詞定義
CIF,指RK芯片中的VIP模塊,用以接收Sensor數(shù)據(jù)并保存到Memory中,僅轉(zhuǎn)存數(shù)據(jù),無ISP功能
DVP,一種并行數(shù)據(jù)傳輸接口,即Digital Video Port
HSYNC,指DVP接口的行同步信號
PCLK,指Sensor輸出Pixel Clock
VSYNC,指DVP接口的場同步信號
V4L2,即Video4Linux2,Linux kernel的視頻處理模塊
視頻格式
視頻格式一般分成BT1120(BT656)和BT601兩種。
BT1120視頻數(shù)據(jù)只支持內(nèi)同步。信號內(nèi)同步的意思是圖像數(shù)據(jù)和同步信號均包含在圖像數(shù)據(jù)中,通過關(guān)鍵字恢復(fù)同步信號??梢詤⒖嘉业牧硪黄┛蚐DI視頻數(shù)據(jù)流格式簡介
BT601協(xié)議采用外同步,外同步是指圖像數(shù)據(jù)和同步數(shù)據(jù)(HS、VS、DE)單獨傳送。
因為內(nèi)同步是將圖像與同步信號一起傳送,因此會有同步分離機(jī)制,所以亮度及色彩不可能全編碼,以8BIT為例,可以傳送的范圍為0-255,但內(nèi)同步一起傳送,實際編碼不可能有256范圍,在ITU-656中大多采用16-235,而ITU-601因為采用外同步,可以傳送0-255 范圍的數(shù)據(jù)。因此,內(nèi)同步的色采及亮度在細(xì)節(jié)上沒有內(nèi)同步好。但是,在串行編碼及低帶寬傳送中,內(nèi)同步可以減少數(shù)據(jù)流,因此,通過內(nèi)同步傳送圖像雖然色彩有一定的損失,但可以換來更低的帶寬。
視頻格式一般在視頻的驅(qū)動程序中進(jìn)行設(shè)置,只有以下兩種格式:
config->type = V4L2_MBUS_BT656;//BT1120 BT656
config->type = V4L2_MBUS_PARALLEL;//BT601
一般BT601使用較多,外同步信號,需要配合行場同步信號。
sensor與isp
sensor與isp之間的關(guān)系圖一般如下所示:
首先ISP也就是ARM芯片端,需要通過I2C總線對sensor進(jìn)行配置,主要通過SCL(時鐘線)和SDA(數(shù)據(jù)線)對sensor的寄存器進(jìn)行配置,可以決定sensor的分辨率、輸出視頻格式(rgb、yuv)、白平衡等進(jìn)行設(shè)置。
部分?jǐn)z像頭可能不含晶振,比如OV7670,所以就需要ISP提供相機(jī)時鐘,也就是XCLK進(jìn)行驅(qū)動,一般在24MHz左右。部分帶有晶振的相機(jī),比如OV2640,由于集成了晶振,所以無需進(jìn)行外部時鐘驅(qū)動。
VS、HS和PCLK是sensor輸出的行場同步信號和像素時鐘。
DATA是sensor輸出的像素值,一般8位較多。
然后對以上的各個部分進(jìn)行介紹。
I2C
由于ARM芯片具有較多的I2C引腳,比如RV1126好像就有5個I2C引腳。每一個相機(jī)的I2C都要連接到對應(yīng)的引腳上,以正點原子的RV1126開發(fā)板為例,I2C就掛載到了I2C1下:
在設(shè)備樹dts中,就要把OV2640的攝像頭節(jié)點放在I2C1下,比如:
&i2c1 {
status = "okay";
clock-frequency = <100000>;
ov2640: camera@3c {
compatible = "ovti,ov2640";
pinctrl-names = "default";
reg = <0x3c>;
......
}
}
攝像頭所支持的I2C時鐘速度最快可達(dá)到400Kbps,同時每一款攝像頭都有專屬的地址,比如ov2640的地址是0x3c,注意地址是硬件設(shè)計死的無法更改。
I2C設(shè)備可以使用i2cdetect工具進(jìn)行調(diào)試,比如查看i2c1下掛載了哪些設(shè)備,可以通過以下命令進(jìn)行查看:
i2cdetect -y 1
若我在0x21處掛載了設(shè)備,將得到:
同時可以使用以下命令查看i2c寄存器中的值,比如我要查看i2c1下地址為0x3c處寄存器的值,可以通過以下名稱查看:
i2cdump -y -f 1 0x3c
值得注意的是有些攝像頭將power_down拉低后,開發(fā)板才能夠通過i2c與相機(jī)寄存器之間進(jìn)行通信,比如上方為拉低了的,下方為未拉低。
另:OV公司的I2C不是標(biāo)準(zhǔn)的I2C總線,為了避開專利,他們采用的是SCCB總線技術(shù),不過經(jīng)過測試與I2C區(qū)別不大。
SCCB是歐姆尼圖像技術(shù)公司(OmniVision)開發(fā)的一種總線,應(yīng)用于OV系列圖像傳感器上。SCCB最主要是閹割了IIC的連續(xù)讀寫的功能,即每讀寫完一個字節(jié)就主機(jī)必須發(fā)送一個NA信號。
XCLK
部分不帶晶振的攝像頭需要提供XCLK像素時鐘進(jìn)行驅(qū)動,在設(shè)備樹中可以通過以下進(jìn)行添加,注意時鐘名字要與驅(qū)動對應(yīng):
比如設(shè)備樹中可能如下:
clocks = <&cru CLK_CIF_OUT>;
clock-names = "xvclk";
驅(qū)動部分對應(yīng)如下:
priv->clk = v4l2_clk_get(&client->dev, "xvclk");
if (IS_ERR(priv->clk))
return -EPROBE_DEFER;
行場同步信號
不同相機(jī)的行場同步信號可能不同,具體可以查詢芯片手冊,不過注意的是芯片手冊不一定準(zhǔn)確,比如OV2640,芯片手冊的時序為:
可以看出是標(biāo)準(zhǔn)的SDI格式,也就是當(dāng)DE也就是HREF為高時,VSYNC為低,VSYNC只在有效像素前產(chǎn)生一段高電平。但是按照這個時序產(chǎn)生的同步信號始終無法抓取到圖像,經(jīng)過抓取之后發(fā)現(xiàn)OV2640輸出的時序如下:
可以看出當(dāng)DE為高時,也就是有效像素部分,VS也為高,基本與手冊中寫的相反,按照上面的時序即可抓取到圖像。
正確OV2640時序的Verilog代碼如下,注意分辨率為800x600,YUYV格式8bit:
parameter ROWS = 600;
parameter COLS = 1600;
parameter ROWS_TOTAL = 672;
parameter COLS_TOTAL = 3840;
parameter ROW_START = 36;
parameter COL_START = 1000;
reg [12:0] rROW;
reg [12:0] rCOL;
always@(posedge wCLK18M)
begin
if(!iRst)
begin
rROW <= 0;
rCOL <= 0;
end
else
begin
if(rCOL==COLS_TOTAL-1)
begin
rCOL <= 0;
rROW <= rROW + 1;
end
else
begin
rCOL <= rCOL + 1;
end
if(rROW == ROWS_TOTAL)
begin
rROW <= 0;
end
end
end
reg r2640DE;
reg r2640VS;
reg [7:0] r2640H;
always@(posedge wCLK18M)
begin
if(rROW >= ROW_START && rROW < (ROW_START + ROWS))
begin
r2640VS <= 1;
if(rCOL >= COL_START && rCOL < (COL_START + COLS))
begin
r2640DE <= 1;
end
else
begin
r2640DE <= 0;
end
end
else
begin
r2640VS <= 0;
end
end
生成的波形如下:
同時也要注意HS和VS的極性,也就是有效時的電平高低,主要收到設(shè)備樹和驅(qū)動的控制,設(shè)備樹部分如下:
&i2c1 {
status = "okay";
// clock-frequency = <400000>;
clock-frequency = <100000>;
ov2640: camera@3c {
compatible = "ovti,ov2640";
pinctrl-names = "default";
pinctrl-0 = <&cifm1_dvp_ctl>;
reg = <0x3c>;
clocks = <&cru CLK_CIF_OUT>;
clock-names = "xvclk";
port {
/* Parallel bus endpoint */
cam_para_out1: endpoint {
remote-endpoint = <&cif_para_in>;
bus-width = <8>;
//data-shift = <2>; /* lines 9:2 are used */
hsync-active = <1>;
vsync-active = <1>;//<1>;
pclk-sample = <1>;
};
};
};
};
&rkcif_dvp {
status = "okay";
port {
cif_para_in: endpoint {
remote-endpoint = <&cam_para_out1>;
bus-width = <8>;
hsync-active = <1>;
vsync-active = <1>;
};
};
};
驅(qū)動部分:
config->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
V4L2_MBUS_DATA_ACTIVE_HIGH;
兩者要與實際情況相匹配。
DATA
sensor輸出的數(shù)據(jù)一般8位居多,也有16位和10位的,RV1126的CIF接口輸入如下:
優(yōu)先使用CIF接口的高位進(jìn)行傳輸。
同時還要對MEDIA_BUS_FMT進(jìn)行配置,與sensor輸出的像素格式對應(yīng),可以參考V4L2的手冊,格式十分豐富。
以O(shè)V2640為例支持以下的格式:
static u32 ov2640_codes[] = {
MEDIA_BUS_FMT_YUYV8_2X8,
MEDIA_BUS_FMT_UYVY8_2X8,
MEDIA_BUS_FMT_YVYU8_2X8,
MEDIA_BUS_FMT_VYUY8_2X8,
MEDIA_BUS_FMT_RGB565_2X8_BE,
MEDIA_BUS_FMT_RGB565_2X8_LE,
};
以MEDIA_BUS_FMT_YUYV8_2X8為例,視頻輸出的格式位YUYV,并且深度是8bit色深,每次只傳輸8bit,兩個像素周期才是一個完整的像素。
抓圖
抓圖一般使用v4l2-ctl進(jìn)行抓圖,對于dvp接口可以在video0進(jìn)行抓圖,對于mipi則不行,抓圖實例如下:
v4l2-ctl -d /dev/video0 --set-fmt-video=width=800,height=600,pixelformat=YUYV8_2X8--stream-mmap=3 --stream-skip=3 --stream-to=./cif.out --stream-count=1 --stream-poll
抓圖成功一般如下所示,會有 < 打印輸出:
并且對于800x600大小YUYV8_2X8格式的圖片一般占用940k存儲空間。
并且可以通過以下python代碼查看像素值:
yuv = "./pic.out"
with open(yuv, "rb") as yuv_f:
yuv_bytes = yuv_f.read()
yuv_data = np.frombuffer(yuv_bytes, np.uint8)
同時在/proc路徑下也會有統(tǒng)計信息得到保存,通過以下命令進(jìn)行查看:文章來源:http://www.zghlxwxcb.cn/news/detail-779967.html
cat /proc/rkcif_dvp
以上就是對dvp相機(jī)的視頻接入的簡單介紹,各位有疑問可以留言,進(jìn)行交流。文章來源地址http://www.zghlxwxcb.cn/news/detail-779967.html
到了這里,關(guān)于基于瑞芯微平臺cif接口dvp相機(jī)的視頻接入(ov2640、rv1126為例)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!