平臺信息:
內核:linux
系統:android
平臺:S5PV310(samsung exynos 4210)
作者:xubin341719(歡迎轉載,請註明作者)
新項目開案,代碼他們還沒給得到,三星那邊辦事流程就是多,煩人(嘿嘿只是說說,流程從另一方面說明了人家標準化的程度高)。看看代碼,把前一段時間工作的內容整理下,發出來。一方面有相同問題的“同學”可以看下,說不定問題就解決了; 再一方面自己工作方面記錄吧,整個流程整理出來,加深自己的印象,技術還得提高呀。這樣利人利己的事多做點好……“爲人民服務!”(我不是**黨,只是技術P民)
這篇比較基礎,做爲科普知識看一下。
android camera(一):camera模組CMM介紹
android camera(二):攝像頭工作原理、s5PV310 攝像頭接口(CAMIF)
android camera(三):camera V4L2 FIMC
android camera(四):camera 驅動 GT2005
一、攝像頭模組(CCM)介紹:
1、camera特寫
攝像頭模組,全稱CameraCompact Module,以下簡寫爲CCM,是影像捕捉至關重要的電子器件。先來張特寫,各種樣子的都有,不過我前一段時間調試那個有點醜。
2、攝像頭工作原理、camera的組成各組件的作用
想完全的去理解,還得去深入,如果是代碼我們就逐步分析,模組的話我們就把它分解開來,看他到底是怎麼工作的。看下它是有那些部分構成的,如下圖所示:
(1)、工作原理:物體通過鏡頭(lens)聚集的光,通過CMOS或CCD集成電路,把光信號轉換成電信號,再經過內部圖像處理器(ISP)轉換成數字圖像信號輸出到數字信號處理器(DSP)加工處理,轉換成標準的GRB、YUV等格式圖像信號。
(2)、CCM 包含四大件: 鏡頭(lens)、傳感器(sensor)、軟板(FPC)、圖像處理芯片(DSP)。決定一個攝像頭好壞的重要部件是:鏡頭(lens)、圖像處理芯片 (DSP)、傳感器(sensor)。CCM的關鍵技術爲:光學設計技術、非球面鏡製作技術、光學鍍膜技術。
鏡頭(lens)是相機的靈魂,鏡頭(lens)對成像的效果有很重要的作用,是利用透鏡的折射原理,景物光線通過鏡頭,在聚焦平面上形成清晰的影像,通過感光材料CMOS或CCD感光器記錄景物的影像。鏡頭廠家主要集中在臺灣、日本和韓國,鏡頭這種光學技術含量高的產業有比較高的門檻,業內比較知名的企業如富士精機、柯尼卡美能達、大立光、Enplas等
傳感器(sensor)是CCM的核心模塊,目前廣泛使用的有兩種:一種是廣泛使用的CCD(電荷藕合)元件;另一種是CMOS(互補金屬氧化物導體)器件。
電荷藕合器件圖像傳感器CCD(Charge Coupled Device),它使用一種高感光度的半導體材料製成,能把光線轉變成電荷,通過模數轉換器芯片轉換成數字信號。CCD由許多感光單位組成,通常以百萬像 素爲單位。當CCD表面受到光線照射時,每個感光單位會將電荷反映在組件上,所有的感光單位所產生的信號加在一起,就構成了一幅完整的畫面。CCD傳感器模塊以日本廠商爲主導,全球規模市場有90%以上被日本廠商壟斷,以索尼、松下、夏普爲龍頭。
互補性氧化金屬半導體CMOS(Complementary Metal-Oxide Semiconductor)主要是利用硅和鍺這兩種元素所做成的半導體,使其在CMOS上共存着帶N(帶–電)和 P(帶+電)級的半導體,這兩個互補效應所產生的電流即可被處理芯片紀錄和解讀成影像。CMOS 傳感器主要美國、臺灣和韓國爲主導,主要生產廠家有美國 OmniVision、Agilent、Micron,臺灣的銳像、原相、泰視等,韓國的三星、現代。
圖像處理芯片(DSP)是CCM的重要組成部分,它的作用是將感光芯片獲得的數據及時快速地傳遞中央處理器並刷新感光芯片,因此DSP芯片的好壞,直接影響畫面品質(比如色彩飽和度,清晰度等)。
FPC柔性電路板(柔性PCB): 簡稱"軟板", 又稱"柔性線路板",連接芯片和手機。起到電信號傳輸作用。
3、camera模組的裝配方式
(1)、定焦模組裝配圖
CCM分爲定焦模組和自動變焦模組,其中定焦模組主要由鏡頭、鏡座、感光集成電路、軟性線路板、補強和鋼片裝配而成,其裝配圖如下:
(2)、自動變焦模組裝配圖
以前我不知道手機上的光學變焦是怎麼會事,以爲那些都是忽悠人的,看這個圖這下明白了,如果你也不知道,看下這個圖,原來裏面有個音圈馬達,這個只有高像素的模組纔有,這個我們不用管,知道怎麼光學變焦就可以了。
自動變焦模組由鏡頭、音圈馬達、底座支架、感光集成電路、驅動集成電路和連接器組成,其裝配圖如下:
(3)、3D模組
傳說中的3D是怎麼會事,多幾臺攝像機拍攝。手機上也有了??有點強大
看人家手機上用的,感覺看着不太好看,高科技的東西開始就是做得醜了一點,我們瞭解有這個東西就行了:
4、攝像頭的一些技術指標
(1)、圖像解析度/分辨率(Resolution)
QSIF/QQVGA |
160 x 120 |
19200 |
|
QCIF |
176 x 144 |
25344 |
|
SIF/QVGA |
320 x 240 |
76800 |
|
CIF |
352 x 288 |
101376 |
10萬像素 |
VGA |
640 x 480 |
307200 |
30萬像素(35萬是指648X488) |
SVGA |
800 x 600 |
480000 |
50萬像素 |
XGA |
1024 x 768 |
786438 |
80萬像素 |
SXGA |
1280 x 1024 |
1310720 |
130萬像素 |
UXGA |
1600 x 1200 |
1920000 |
200萬像素 |
QXGA |
2048 x 1536 |
3145728 |
300萬像素(320W) |
QSXGA |
2592 x 1944 |
5038848 |
500萬像素 |
|
2816 x 2112 |
2947392 |
600萬像素 |
|
3072 x 2304 |
7077888 |
700萬像素 |
|
3200 x 2400 |
7680000 |
770萬像素 |
|
3264 x 2448 |
7990272 |
800萬像素 |
|
3876 x 2584 |
10015584 |
1000萬像素 |
(2)、圖像格式(imageFormat/Colorspace)
RGB24,420是目前最常用的兩種圖像格式。
RGB24:表示R、G、B三種顏色各8bit,最多可表現256級濃淡,從而可以再現256*256*256種顏色。
I420:YUV格式之一。其它格式有:RGB565,RGB444,YUV4:2:2等。
(3)、自動白平衡調整(AWB)
定義:要求在不同色溫環境下,照白色的物體,屏幕中的圖像應也是白色的。色溫表示光譜成份,光的顏色。色溫低表示長波光成分多。當色溫改變時,光源中三基色(紅、綠、藍)的比例會發生變化,需要調節三基色的比例來達到彩色的平衡,這就是白平衡調節的實際。
(4)、圖像壓縮方式
JPEG:(joint photo graphicexpert group)靜態圖像壓縮方式。一種有損圖像的壓縮方式。壓縮比越大,圖像質量也就越差。當圖像精度要求不高存儲空間有限時,可以選擇這種格式。目前大部分數碼相機都使用JPEG格式。
(5)、彩色深度(色彩位數)
反映對色彩的識別能力和成像的色彩表現能力,實際就是A/D轉換器的量化精度,是指將信號分成多少個等級。常用色彩位數(bit)表示。彩色深度越高,獲得的影像色彩就越豔麗動人。現在市場上的攝像頭均已達到24位,有的甚至是32位
(6)、圖像噪音
指的是圖像中的雜點干撓。表現爲圖像中有固定的彩色雜點。
(7)、視角
與人的眼睛成像是相成原理,簡單說就是成像範圍。
(8)、輸出/輸入接口
串行接口(RS232/422):傳輸速率慢,爲115kbit/s
並行接口(PP):速率可以達到1Mbit/s
紅外接口(IrDA):速率也是115kbit/s,一般筆記本電腦有此接口
通用串行總線USB:即插即用的接口標準,支持熱插拔。USB1.1速率可達12Mbit/s,USB2.0可達480Mbit/s
IEEE1394(火線)接口(亦稱ilink):其傳輸速率可達100M~400Mbit/s
今天 有點晚了,後繼續分析camera sensor接口、s5pv310 CAMIF接口、V4L2、FIMC、和我們最終的sensor驅動。
關鍵詞:android camera CMM 模組 camera參數 CAMIF
平臺信息:
內核:linux
系統:android
平臺:S5PV310(samsung exynos 4210)
作者:xubin341719(歡迎轉載,請註明作者)
android camera(一):camera模組CMM介紹
android camera(二):攝像頭工作原理、s5PV310 攝像頭接口(CAMIF)
android camera(三):camera V4L2 FIMC
android camera(四):camera 驅動 GT2005
一、攝像頭工作原理
上一篇我們講了攝像頭模組的組成,工作原理,做爲一種瞭解。下面我們析攝像頭從寄存器角度是怎麼工作的。如何閱讀攝像頭規格書(針對驅動調節時用到關鍵參數,以GT2005爲例)。
規格書,也就是一個器件所有的說明,精確到器件每一個細節,軟件關心的寄存器、硬件關心的電氣特性、封裝等等。單單驅動方面,我們只看對我們有用的方面就可以了,沒必要全部看完。主要這樣資料全都是鳥語(En),全部看完一方面時間上會用的比較多,找到關鍵的地方就行了。
1、camera的總體示意圖如下:控制部分爲攝像頭上電、IIC控制接口,數據輸出爲攝像頭拍攝的圖傳到主控芯片,所有要有data、行場同步和時鐘號。GT2005/GT2015是CMOS接口的圖像傳感器芯片,可以感知外部的視覺信號並將其轉換爲數字信號並輸出。
我們需要通過MCLK給攝像頭提供時鐘,RESET是復位線,PWDN在攝像頭工作時應該始終爲低。PCLK是像素時鐘,HREF是行參考信號,VSYNC是場同步信號。一旦給攝像頭提供了時鐘,並且復位攝像頭,攝像頭就開始工作了,通過HREF,VSYNC和PCLK同步傳輸數字圖像信號。 數據是通過D0~D7這八根數據線並行送出的。
(1)、Pixel Array
GT2005陣列大小爲 1268 列、1248 行,有效像素爲 1616 列, 1216 行。也就是說攝像頭爲1600X1200的時候,像素點要多於這個,去除邊緣一部分,保證圖像質量吧。
(2)、IIC 這個不用說了,攝像頭寄存器初始化的數據都從這裏傳輸的,所有的IIC器件都一樣的工作,來張圖吧,後面做詳細分析;
下面這一部分在調試驅動的過程中比較重要了:
(3)、MCLK
電子元件工作都得要個時鐘吧,攝像頭要工作,這個就是我們所要的時鐘,在主控制芯片提供,這個時鐘一定要有,要不然攝像頭不會工作的。
(4)、上下電時序,這個要接規格書上來,注間PWDN、RESETB這兩個腳,不同的攝像頭不太一樣,這個圖是上電時序,上電時參考一下,知道在那裏看就行;
(5)PCLK \D1~D7
攝像頭得到的數據要傳出來吧,要有數據,當然數據出來要有時鐘和同步信號了,看下它的時序,和LCD顯示的時序一樣,道理是一樣的:
(6)、主要的寄存器:分辨率、YUV順序、X軸、Y軸鏡相、翻轉
以上工作完成後,也許還有一些問題,分辨率太小; YUV順序不對圖像不對; XY圖像方向。這些工作完成後,如果還有什麼細節的問題,如果你想花時間,看規格書裏面的寄存器可以解決的,如果不想看,找模組廠的FAE,他們專業的,很快會幫你搞定。
(7)、攝像頭的硬件接口
二、S5pv310上Camera主控芯片上的硬件接口
1、CAMIF Camera Interface
先看一下攝像頭接口框圖:(這個看着有點抽像,我們放這裏,先了解一下,其實驅動中一般不會涉及到這裏,不過我們這裏分析了,就把這個帶出來了)
(1)、攝像頭接口的主要屬性:
a、支持多種輸入接口:(就是上面我們看到的四模式)
DMA (AXI 64-bitinterface) 模式;
MIPI (CSI) 模式;
ITU-R BT 601/ 656/ 709模式;
Direct FIFO (PlayBack)模式;
b、支持多種輸出模式:
DMA (AXI 64-bitinterface) 模式;
Direct FIFO 模式;
c、支持數碼變焦Digital Zoom In (DZI) capability;
d、支持多攝像頭輸入;
e、 支持視頻同步信號極性可編程控制;
f、支持最大輸入分辨率爲8192X8192;
g、支持圖像翻轉(X軸、Y軸鏡相,90、180、270翻轉);
h、支持多種圖片格式;
i、支持捕獲幀控制;
j、支持的圖像特效。
2、FIMC Fully InteractiveMobile Camera
攝像頭的採集的數據要CPU無法直接處理,主控芯片裏面集成了Camera控制器,叫FIMC(FullyInteractive Mobile Camera)。攝像頭需要先把圖像數據傳給控制器,經過控制器處理(裁剪拉昇後直接預覽或者編碼)之後交給CPU處理。實際上攝像頭工作需要的時鐘(MCLK)也是FIMC給它提供的。
在s5pv310上的攝像頭接口是一個FIMC(完全交互式移動相機接口),支持ITUR BT-601-605標準、AMX接口、MIPI接口
MIPI 、ITU、AMX
(1)、ITU國際電信聯盟無線電通信部門ITU-RRadiocommunication Sector of ITU 簡稱ITU-RITU-R BT.601 16位數據傳輸;Y、U、V信號同時傳輸,是並行數據,行場同步單獨輸出。
ITU-R BT.6568/10位數據傳輸;不需要同步信號;串行數據傳輸;傳輸速率是601的2倍;先傳Y,後傳UV。行場同步信號嵌入在數據流中。
(2)、MIPI(移動行業處理器接口)是MobileIndustry Processor Interface的縮寫 MIPI 規範:Camera工作組:MIPI Camera Serial Interface 1.0specification .Camera Serial Interface 2 v1.0 (CSI-2)
(3)、AMX(Advanced eXtensible Interface)是一種總線協議,該協議是ARM公司提出的AMBA(Advanced Microcontroller BusArchitecture)3.0協議中最重要的部分,是一種面向高性能、高帶寬、低延遲的片內總線。
3、接口信息
FIMC信號定義如下所示(YCbCr模式)
Signal |
I/O |
Description |
Type |
HREF |
I |
行同步信號 |
|
PCLK |
I |
像素時鐘 |
|
DATA[7:0] |
I |
像素數據 |
|
FIELD |
O |
FIELD信號 |
|
MCLK |
O |
系統時鐘信號 |
通過CAM_MCLK給攝像頭提供時鐘,RST是復位線,PWDN在攝像頭工作時應該始終爲低。HREF是行參考信號,PCLK是像素時鐘,VSYNC是場同步信號。一旦給攝像頭提供了時鐘,並且復位攝像頭,攝像頭就開始工作了,通過HREF,PCLK和VSYNC同步傳輸數字圖像信號。數據是通過DATA0~DATA7這八根數據線並行送出的。
4、不同接口模式的工作時序
ITU-R BT 656輸入時序圖,這種方式下同步信號已經內嵌到視頻數據中了,因此不需要額外的行和幀同步信號。
ITU-R BT 601輸入時序圖,這種方式下行和幀同步信號獨立於視頻數據,因此需要同步信號。
(ITU-R BT 601: 16位數據傳輸;21芯;Y、U、V信號同時傳輸。
ITU-R BT 656: 9芯,不需要同步信號;8位數據傳輸;串行視頻傳輸;傳輸速率是601的2倍;先傳Y,後傳UV。)
同步信號的時延參數
Ø t1:表示VSYNC前、後插入週期
Ø t2:表示HREF前插入週期
Ø t3:表示 HREF寬度
Ø t4:表示HREF後插入週期
5、camera的時鐘域,三個時鐘:系統時鐘、PCLK、MCLK
每個攝像頭接口包括三個時鐘域,每一個時鐘域是系統總線時鐘,第二個是攝像頭像素時鐘PCLK,第三個時鐘域爲內部時鐘MCLK。系統總線時鐘必需高於PCLK, CAM_MCLK 必需固定頻率分頻,如PLL時鐘。如果有外部時鐘晶振,CAM_MCLK 空掉。不需要同步MMCLK,PCLK應該與schmitt-triggered電平移位器連接。
6、硬件接口電路
主控芯片上的接口:
camera 接口
關鍵詞:android camera CMM 模組 camera參數 CAMIF V4L2
平臺信息:
內核:linux
系統:android
平臺:S5PV310(samsung exynos 4210)
作者:xubin341719(歡迎轉載,請註明作者)
android camera(一):camera模組CMM介紹
android camera(二):攝像頭工作原理、s5PV310 攝像頭接口(CAMIF)
android camera(三):camera V4L2 FIMC
android camera(四):camera 驅動 GT2005
下載:常用攝像頭規格書(個別有android驅動程序) :bf3703 30W、gc0308 30W、ov7670、gt2005 200W、gt2015 200W、NT99250 200W、s5k5ba 200W、s5k4ba前面兩篇說的有點多了,不過多瞭解點東西也挺好的,遇到問題時可以有更多的思路,真正驅動是從這一塊開始。一般BSP的camera都是完好的,我們只用關心驅動這些就可以了。
1. V4L2
1)簡介
在Linux中,攝像頭方面的標準化程度比較高,這個標準就是V4L2驅動程序,這也是業界比較公認的方式。
V4L全稱是Video for Linux,是Linux內核中標準的關於視頻驅動程序,目前使用比較多的版本是Video for Linux 2,簡稱V4L2。它爲Linux下的視頻驅動提供了統一的接口,使得應用程序可以使用統一的API操作不同的視頻設備。從內核空間到用戶空間,主要的數據流和控制類均由V4L2驅動程序的框架來定義。
V4L2驅動程序一般只提供Video數據的獲得,而如何實現視頻預覽,如何向上層發送數據,如何把純視頻流和取景器、視頻錄製等實際業務組織起來,都是camera的硬件抽象層需要負責的工作。
V4L2驅動核心實現爲如下文件:drivers/media/video/v4l2-dev.c。
V4l2-dev.h中定義的video_device是V4L2驅動程序的核心數據結構,它爲具體的攝像頭sensor驅動提供了接口調用。
V4l2的採集過程(應用程序):
1) 打開設備,獲得文件描述符;
2) 設置圖片格式;
3) 分配緩衝區;
4) 啓動採集過程,讀取數據;
5) 停止採集,關閉設備。
2)數據結構
V4L2的主要數據結構是video_device,定義在v4l2_dev.h中:
- struct video_device
- {
- /* device ops */
- const struct v4l2_file_operations *fops; /*接口函數指針*/
- /* sysfs */
- struct device dev; /* v4l 設備結構 */
- struct cdev *cdev; /* 字符設備結構*/
- /* Set either parent or v4l2_dev if your driver uses v4l2_device */
- struct device *parent; /* 設備父指針 */
- struct v4l2_device *v4l2_dev; /* v4l2設備指針*/
- /* device info */
- char name[32]; /*設備名稱*/
- int vfl_type;
- /* 'minor' is set to -1 if the registration failed */
- int minor; /*次設備號*/
- u16 num;
- /* use bitops to set/clear/test flags */
- unsigned long flags;
- /* attribute to differentiate multiple indices on one physical device */
- int index;
- /* V4L2 file handles */
- spinlock_t fh_lock; /* Lock for all v4l2_fhs */
- struct list_head fh_list; /* List of struct v4l2_fh */
- int debug; /* debug 級別*/
- /* Video 標準變量 */
- v4l2_std_id tvnorms; /* Supported tv norms */
- v4l2_std_id current_norm; /* Current tvnorm */
- /* 回調函數 */
- void (*release)(struct video_device *vdev);
- /* ioctl 回調函數 */
- const struct v4l2_ioctl_ops *ioctl_ops;
- };
主要接口函數有:
intvideo_register_device(struct video_device *vdev, int type, int nr);
static intv4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
2. FIMC
1)簡介
FIMC這個模塊不僅僅是一個攝像頭的控制接口,它還承擔着V4L2的output功能和overlay的功能。
FIMC的驅動在內核中的位置:drivers/media/video/samsung/fimc
它包含下邊的文件:
fimc_regs.c
fimc_capture.c
fimc_dev.c
fimc_output.c
fimc_overlay.c
fimc_v4l2.c
它們的組織關係如下:
可以看到,FIMC的驅動實現了v4l2所有的接口,可以分爲v4l2-input設備接口,v4l2-output設備接口以及v4l2-overlay設備接口。這裏我們主要關注v4l2-input設備接口,因爲攝像頭屬於視頻輸入設備。
fimc_v4l2.c裏面註冊了很多的回調函數,都是用於實現v4l2的標準接口的,但是這些回調函數基本上都不是在fimc_v4l2.c裏面實現的,而是有相應的.c分別去實現。比如:
v4l2-input設備的操作實現:fimc_capture.c
v4l2-output設備的操作實現: fimc_output.c
v4l2-overlay設備的操作實現: fimc_overlay.c
這些代碼其實都是和具體硬件操作無關的,這個驅動把所有操作硬件寄存器的代碼都寫到一個文件裏面了,就是fimc40_regs.c。這樣把硬件相關的代碼和硬件無關的代碼分開來實現是非常好的方式,可以最大限度的實現代碼複用。
2) 數據結構
FIMC的主要數據結構fimc_control,定義在fimc.h中:
- struct fimc_control {
- int id; /* 控制器 id */
- char name[16];
- atomic_t in_use;
- void __iomem *regs; /* 寄存器 i/o */
- struct clk *clk; /* interface clock */
- struct regulator *regulator; /* pd regulator */
- struct fimc_meminfo mem; /* for reserved mem */
- /* kernel helpers */
- struct mutex lock; /* controller lock */
- struct mutex alloc_lock;
- struct mutex v4l2_lock;
- wait_queue_head_t wq;
- struct device *dev;
- int irq;
- /* v4l2 related */
- struct video_device *vd;
- struct v4l2_device v4l2_dev;
- /* fimc specific */
- struct fimc_limit *limit; /* H/W limitation */
- struct s3c_platform_camera *cam; /* activated camera */
- struct fimc_capinfo *cap; /* capture dev info */
- struct fimc_outinfo *out; /* output dev info */
- struct fimc_fbinfo fb; /* fimd info */
- struct fimc_scaler sc; /* scaler info */
- struct fimc_effect fe; /* fimc effect info */
- enum fimc_status status;
- enum fimc_log log;
- u32 ctx_busy[FIMC_MAX_CTXS];
- };
- struct video_device fimc_video_device[FIMC_DEVICES] = {
- [0] = {
- .fops = &fimc_fops,
- .ioctl_ops = &fimc_v4l2_ops,
- .release = fimc_vdev_release,
- },
- [1] = {
- .fops = &fimc_fops,
- .ioctl_ops = &fimc_v4l2_ops,
- .release = fimc_vdev_release,
- },
- [2] = {
- .fops = &fimc_fops,
- .ioctl_ops = &fimc_v4l2_ops,
- .release = fimc_vdev_release,
- },
- };
fb_ops結構體是針對v4l2設備的基本操作,定義如下:
- static const struct v4l2_file_operations fimc_fops = {
- .owner = THIS_MODULE,
- .open = fimc_open,
- .release = fimc_release,
- .ioctl = video_ioctl2,
- .read = fimc_read,
- .write = fimc_write,
- .mmap = fimc_mmap,
- .poll = fimc_poll,
- };
3)FIMC初始設置
在S5PV210中,FIMC初始設置代碼在 /drivers/ arch/arm/mach-s5pv210/mach-smdkv310.c中:
- static struct s3c_platform_fimc fimc_plat = {
- .srclk_name = "mout_mpll",
- .clk_name = "sclk_fimc",
- .lclk_name = "sclk_fimc_lclk",
- .clk_rate = 166750000,
- .default_cam = CAMERA_CSI_C,
- .camera = {
- &mt9p111,//5M back cam
- &s5k6aafx,///1.3M front cam
- },
- .hw_ver = 0x43,
- };
對於GPIO的配置代碼在 /drivers/ arch/arm/mach-s5pv210/setup-fimc0.c中:
- oid s3c_fimc0_cfg_gpio(struct platform_device *pdev)
- {
- int i = 0;
- /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */
- for (i = 0; i < 8; i++) {
- s3c_gpio_cfgpin(S5PV210_GPE0(i), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPE0(i), S3C_GPIO_PULL_NONE);
- }
- /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */
- for (i = 0; i < 5; i++) {
- s3c_gpio_cfgpin(S5PV210_GPE1(i), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(S5PV210_GPE1(i), S3C_GPIO_PULL_NONE);
- }
- /* CAM B port(b0011) : DATA[0-7] */
- for (i = 0; i < 8; i++) {
- s3c_gpio_cfgpin(S5PV210_GPJ0(i), S3C_GPIO_SFN(3));
- s3c_gpio_setpull(S5PV210_GPJ0(i), S3C_GPIO_PULL_NONE);
- }
- /* CAM B port(b0011) : PCLK, VSYNC, HREF, FIELD, CLCKOUT */
- for (i = 0; i < 5; i++) {
- s3c_gpio_cfgpin(S5PV210_GPJ1(i), S3C_GPIO_SFN(3));
- s3c_gpio_setpull(S5PV210_GPJ1(i), S3C_GPIO_PULL_NONE);
- }
- }
4)接口函數
FIMC的主要回調函數如下,實現在fimc_v4l2.c中:
- onst struct v4l2_ioctl_ops fimc_v4l2_ops = {
- .vidioc_querycap = fimc_querycap,
- .vidioc_reqbufs = fimc_reqbufs,
- .vidioc_querybuf = fimc_querybuf,
- .vidioc_g_ctrl = fimc_g_ctrl,
- .vidioc_s_ctrl = fimc_s_ctrl,
- .vidioc_s_ext_ctrls = fimc_s_ext_ctrls,
- .vidioc_cropcap = fimc_cropcap,
- .vidioc_g_crop = fimc_g_crop,
- .vidioc_s_crop = fimc_s_crop,
- .vidioc_streamon = fimc_streamon,
- .vidioc_streamoff = fimc_streamoff,
- .vidioc_qbuf = fimc_qbuf,
- .vidioc_dqbuf = fimc_dqbuf,
- .vidioc_enum_fmt_vid_cap = fimc_enum_fmt_vid_capture,
- .vidioc_g_fmt_vid_cap = fimc_g_fmt_vid_capture,
- .vidioc_s_fmt_vid_cap = fimc_s_fmt_vid_capture,
- .vidioc_try_fmt_vid_cap = fimc_try_fmt_vid_capture,
- .vidioc_enum_input = fimc_enum_input,
- .vidioc_g_input = fimc_g_input,
- .vidioc_s_input = fimc_s_input,
- .vidioc_g_parm = fimc_g_parm,
- .vidioc_s_parm = fimc_s_parm,
- .vidioc_queryctrl = fimc_queryctrl,
- .vidioc_querymenu = fimc_querymenu,
- .vidioc_g_fmt_vid_out = fimc_g_fmt_vid_out,
- .vidioc_s_fmt_vid_out = fimc_s_fmt_vid_out,
- .vidioc_try_fmt_vid_out = fimc_try_fmt_vid_out,
- .vidioc_g_fbuf = fimc_g_fbuf,
- .vidioc_s_fbuf = fimc_s_fbuf,
- .vidioc_try_fmt_vid_overlay = fimc_try_fmt_overlay,
- .vidioc_g_fmt_vid_overlay = fimc_g_fmt_vid_overlay,
- .vidioc_s_fmt_vid_overlay = fimc_s_fmt_vid_overlay,
- };
對於寄存器的操作,實現都在fimc_regs.c文件中,如
- int fimc_hwset_camera_source(struct fimc_control *ctrl)
- {
- struct s3c_platform_camera *cam = ctrl->cam;
- u32 cfg = 0;
- cfg |= S3C_CISRCFMT_ITU601_8BIT;
- cfg |= cam->order422;
- if (cam->type == CAM_TYPE_ITU)
- cfg |= cam->fmt;
- cfg |= S3C_CISRCFMT_SOURCEHSIZE(cam->width);
- cfg |= S3C_CISRCFMT_SOURCEVSIZE(cam->height);
- writel(cfg, ctrl->regs + S3C_CISRCFMT);
- return 0;
- }
關鍵詞:android camera CMM 模組 camera參數 GT2005 攝像頭常見問題
平臺信息:
內核:linux系統:android
平臺:S5PV310(samsung exynos 4210)
作者:xubin341719(歡迎轉載,請註明作者)
android camera(一):camera模組CMM介紹
android camera(二):攝像頭工作原理、s5PV310 攝像頭接口(CAMIF)
android camera(三):camera V4L2 FIMC
android camera(四):camera 驅動 GT2005
攝像頭主要參數:
1、MCLK 24MHz;
2、PCLK 48~52MHz~;
3、電壓 1.8V(1.5V)、2.8V;
4、scl(IIC時鐘)100KHz或者400KHz。
一、攝像頭驅動
我們以GT2005爲例,來講述一個攝像頭驅動的調試過程:
攝像頭和主控的關係圖,如下:
攝像頭驅動比較簡單,完成一面三大步就可以:
攝像頭的上電、時鐘這些基本條件;
IIC保證攝像頭的初始化;
攝像頭工作後傳回數據到主控。
完成這三個步驟就完成了攝像頭基本工作的調試。
1、 攝像頭的上電、時鐘這些基本條件的實現
電源部分,上電時對應規格書,確認上電時序;MCLK攝像頭的主時鐘是否提供,看下面是和電和規格書中的
(1)、主意攝像頭工作要兩組電壓:1.8V(1.5V)、2.8V還有MCLK
程序中對電源控制:我們在arch\arm\mach-smdkv310.c中,完成上面兩個步驟的代碼,(這一點不同平臺也許有所不同,這裏這是一個實例,這部分代碼只是針對三星平臺的)
- #ifdef CONFIG_VIDEO_GT2005
- static void set_cam2005_main_power(int onoff)
- {
- unsigned int gpio;
- int err;
- if(onoff)
- {
- err = gpio_request(S5PV210_GPB(2), "GPB");
- if (err)
- printk(KERN_ERR "#### failed to request GPB2 for CAM\n");
- s3c_gpio_cfgpin(S5PV210_GPB(2),S3C_GPIO_OUTPUT);
- s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);
- gpio_direction_output(S5PV210_GPB(2), 1);
- gpio_free(S5PV210_GPB(2));
- //RESET
- err = gpio_request(S5PV210_GPE1(4), "GPE1");
- if (err)
- printk(KERN_ERR "#### failed to request GPE1_4 for CAM\n");
- s3c_gpio_setpull(S5PV210_GPE1(4), S3C_GPIO_PULL_NONE);
- gpio_direction_output(S5PV210_GPE1(4),0);
- mdelay(100);
- gpio_direction_output(S5PV210_GPE1(4), 1);
- gpio_free(S5PV210_GPE1(4));
- //PWDN CAM_back
- err = gpio_request(S5PV210_GPB(4), "GPB");
- if (err)
- printk(KERN_ERR "#### failed to request GPB4 for CAM\n");
- s3c_gpio_cfgpin(S5PV210_GPB(4),S3C_GPIO_OUTPUT);
- s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
- gpio_direction_output(S5PV210_GPB(4), 0);
- mdelay(100);
- gpio_direction_output(S5PV210_GPB(4), 1);
- gpio_free(S5PV210_GPB(4));
- }
- else
- {
- ………………
- }
- return;
- }
- #endif
提供MCLK代碼如下:
- static int smdkv210_cam_clk_init(void)
- {
- unsigned int tempvalue=0;
- tempvalue = readl(S5P_CLK_DIV1);
- tempvalue = (tempvalue &0xffff0fff);
- writel(tempvalue,S5P_CLK_DIV1);
- tempvalue = readl(S5P_CLK_SRC1);
- tempvalue = (tempvalue &0xffff0fff)|0x00001000;
- writel(tempvalue,S5P_CLK_SRC1);
- return 0;
- }
這時拿示波器抓到上電時的波形和MCLK24MHZ的時鐘,信號就說明我們完成了這一步,其實在實際工作中,我們一般出問題的時候纔會測這些數據,確認問題點。
上電時序:
(1)、上電時序;
(2)、MCLK如下所示。
2、 IIC和一些參數的配置
- #ifdef CONFIG_VIDEO_GT2005
- static struct GT2005_platform_data GT2005_plat = {
- .default_width = 640,
- .default_height = 480,
- .pixelformat = V4L2_PIX_FMT_UYVY, // .freq = 24000000,
- .is_mipi = 0,
- };
- static struct i2c_board_info GT2005_i2c_info = {
- I2C_BOARD_INFO("GT2005", 0x78 >> 1), //1、IIC地址
- .platform_data = >2005_plat,
- };
- static struct s3c_platform_camera GT2005 = {
- #ifdef CAM_ITU_CH_A
- .id = CAMERA_PAR_A,
- #else
- .id = CAMERA_PAR_B,
- #endif
- .type = CAM_TYPE_ITU, //2、數據接口選擇(ITU\MIPI等)
- .fmt = ITU_601_YCBCR422_8BIT,
- .order422 = CAM_ORDER422_8BIT_CBYCRY, //3、圖像數據格式
- .i2c_busnum = 1,
- .info = >2005_i2c_info,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .srclk_name = "mout_mpll", //4、這部分關係到時鐘
- .clk_name = "sclk_cam1",
- .clk_rate = 24000000, /* 24MHz */
- .line_length = 640, /* 640*480 */
- /* default resol for preview kind of thing */
- .width = 640,
- .height = 480,
- .window = {
- .left = 16,
- .top = 0,
- .width = (640 - 16),
- .height = 480,
- },
- /* Polarity */ //5、信號的極性, .inv_pclk = 0,
- .inv_vsync = 1,
- .inv_href = 0,
- .inv_hsync = 1,
- .initialized = 0,
- .cam_power=set_cam2005_main_power
- };
- #endif
注意下面幾個參數:
(1)、IIC地址
(2)、數據接口選擇(ITU\MIPI等),這幾個數據接口我們在前面提到過;
(3)、圖像數據格式 ,這就是我們前面提到的YVU\UVY之類不同的數據順序;
(4)、這部分關係到時鐘;
(5)、輸出信號的極性,就是我們PCLK、VSYNC、HSVNC這些信號的極性,不正確時會沒有圖像之類現象,這個也要注意了。
完成這一步確認IIC通信是否正常,如下圖所抓到波形:
3、 完成上面兩步,攝像頭基本配置完成,我們確認下輸出端PCLK、VHSN、SVSN、D1-D7
二、攝像頭調試過程中常遇到的問題
1、錄相在預覽時正常,播放錄像時花屏(程序解釋爲三星s5pv210/s5pv310是的,其它的可以參考,找相應代碼)
原因分析:
(1)錄相用fimc2,
在android/device/samsung/proprietary/libcamera/SecCamera.cpp中
int SecCamera::startRecord(void)
- m_cam_fd_rec = open(CAMERA_DEV_NAME2, O_RDWR);
- vendor\sec\sec_proprietary\smdkc110\libcamera\SecCamera.h
- #define CAMERA_DEV_NAME2 "/dev/video2"
android/device/samsung/proprietary/libcamera/SecCameraHWInterface.cpp中
void CameraHardwareSec::m_initDefaultParameters(int camera_id)
- int default_preview_pixel_format = mSecCamera->getPreviewDefaultPixelFormat();
- switch (default_preview_pixel_format) {
- default:
- case V4L2_PIX_FMT_NV21:
- p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
- break;
- case V4L2_PIX_FMT_NV12T:
- p.setPreviewFormat("yuv420sp_tiled");
- break;
- }
- 其中mSecCamera->getPreviewDefaultPixelFormat()在
- vendor\sec\sec_proprietary\smdkc110\libcamera\SecCamera.cpp中實現,
- int SecCamera::getPreviewDefaultPixelFormat(void)
- {
- return DEFAULT_PREVIEW_PIXEL_FORMAT;
- }
- 在android/device/samsung/proprietary/libcamera/SecCamera.h中設定初始值。我們這裏設的是
- #ifdef DUAL_PORT_RECORDING
- #define DEFAULT_PREVIEW_PIXEL_FORMAT (V4L2_PIX_FMT_NV21)
- #else
- #define DEFAULT_PREVIEW_PIXEL_FORMAT (V4L2_PIX_FMT_NV12T)
- #endif
以上得出視頻格式爲V4L2_PIX_FMT_NV21。
2、圖像干擾問題,如下圖所示
原因可能是:
(1)、攝像頭模組有問題,換一個攝像頭試一下;
(2)、數據線驅動能力不足,這個可以在攝像頭寄存器裏面改,問下攝像頭模組FAE,看改那些地方;
(3)、兩個攝像頭共用數據線時,不工作的攝像頭會把工作的數據信號減弱;
(4)、PCB 走線太長,也會有干擾,不過我覺得這個可能性小,調試好就一款這樣的的,模組廠FAE說的,不過他們模組本身也有問題,兩方面因素都有吧:PCB(線過長)、模組打樣也有問題。
3、YUV順序不對:
yuv順序不對時,出現如下現象。
看下攝像頭規格書,把相應寄存器的值改一下就可以了。如下以紅框裏是不同yuv順序,找到改爲相應的。
4、 預覽方向不對(攝像頭寄存器只能改以 180度爲基數的,90度的就要在FIMC中改)
想知道和比較明確說明翻轉角度,最常用的就是寫一個“F”,然後看預覽裏的是怎麼轉的。
上面有90度的翻轉,因爲這是FIMC中的寄存器,一般不會改這一部分的值。要不就在模組寄存器中改,要不就在上層。上面只是說明如何去確認圖像翻轉。
看下GT2005關於翻轉的寄存器吧:
5、 雜光,鬼影:
其行業的專業術語統稱爲Flare,是指在拍攝光源或者強光物體時,邊緣出現光影或出現一個完整物體的影子,而且這種現象只能減輕不能完全消失,原因是由於鏡片的材質導致光線不但存在折射還存在反射,整機由於鏡頭面到保護鏡片距離很大會更明顯!
6、 常見問題相關
攝像頭效果評測都有哪些?
以上以gt2005爲例,說了一下攝像頭驅動,和驅動中常見到的問題,如果上面的問題解決,攝像頭點亮,說明在平臺是運行是沒問題的,小的問題和細節,要找模組廠的FAE過來協助解決,不過你想多研究一下的話,也可以,如果項目允許,就多看看,做到調試一個驅動,所有問題都瞭解,這樣對工作經驗、積累很重要的,希望對大家有用。
- int fimc_hwset_enable_irq(struct fimc_control *ctrl, int overflow, int level)
- {
- u32 cfg = readl(ctrl->regs + S3C_CIGCTRL);
- cfg &= ~(S3C_CIGCTRL_IRQ_OVFEN | S3C_CIGCTRL_IRQ_LEVEL);
- cfg |= S3C_CIGCTRL_IRQ_ENABLE;
- if (overflow)
- cfg |= S3C_CIGCTRL_IRQ_OVFEN;
- if (level)
- cfg |= S3C_CIGCTRL_IRQ_LEVEL;
- writel(cfg, ctrl->regs + S3C_CIGCTRL);
- return 0;
- }