OV9712 CMOS基於JZ4775調試(三)

    新拿到的硬件,是好是壞,或者有沒有一些大意或細節的錯誤,當然需要驅動程序並結合一些電氣工具如(示波器)去檢測.

1.SCCB:

 當然這是最首檢測也是必須檢測的.這裏我是用iic-tools工具(LINUX平臺支持用戶空間驅動的項目,需要內核編譯相關的支持).源碼可以網上搜索移植.後續會提供我這邊提供整理簡化的IIC-TOOLS源碼.iic-tools是LINUX平臺調試IIC設備的利器.一共有i2cdetect,i2cset,i2cget,i2cdump四個工具,可以遍歷iic總線上的設備.其具體用法可網上搜索.OV9712標識了其SCCB設備地址爲0x60,如果i2cdetect出來的結果和其設備地址有出入,就需要檢查一下硬件了.

    當然,前期是可以用iic-tools工具大體檢測,如果是有特殊接口API要求,則就需要具體的API編程.例如下面是我獲取OV9712的PID的函數:

unsigned short ov9712GetId(int iic_fd)
{
        unsigned short pid = 0;
        unsigned char tmp = 0;

        iic_set_addr(iic_fd,OV9712ADDR);

        tmp = iic_read(iic_fd,PIDHADDR);
        pid = tmp;
        pid = pid << 8;

        tmp = iic_read(iic_fd,PIDLADDR);
        pid = pid | tmp;

        if(0x9711 == pid)
                printf("Found Sensor OV9712.So Lucky!\n");
        else
                printf("Oops:Miss OV9712.\n");

        return pid;
}
    0x9711是OV9712的產品ID,可以查看其數據手冊.

    這裏曾遇到個問題,就是SCCB通訊失敗,原因是OV9712必須有MCLK纔可以SCCB通訊的.


2.初始化OV9712:

  確認SCCB通訊是沒問題的,就直接往OV9712堆sample code吧.把原廠提供的初始化代碼通過SCCB協議,往裏面塞.塞完寄存器後大體量一下MCLK、VSYNC、HSYNC、PCLK及DATA引腳,都有信號輸出並且是正常的.截取了一部分原始數據鋪在320x240的屏上顯示只有一些彩條亂七八糟的.出現這種情況當時就往兩個方向想了:

一個是極性問題;第二個對出來的圖像數據直接鋪屏(RGB565)的問題.

    2-1.極性匹配:

  廠家提供的代碼裏面間沒有對VSYNC、HSYNC和PCLK的極性進行重新配置,就是採用默認的.於是查找OV9712數據手冊找到VSYNC、HSYNC、PCLK的極性控制寄存器.如下:

  可見,OV9712的VSYNC、HSYNC默認的極性是Positive,即上升沿有效.

  注意,這裏不要這裏的寄存器坑了,HSYNC默認確實是positive,但是前提是你選定的是HSYNC模式.OV9712支持三種模式:HREF、HSYNC、CCIR565.默認的就是HERF模式而不是HSYNC模式.HERF和HSYNC是同一個pin腳,不同的是,HERF模式下,HERF引腳爲低的時候VSYNC引腳輸出纔有效.見OV9712的數據手冊的時序圖,如下:

  

  因此,在HREF模式下,是下降沿有效的.在這種模式下主控端需要配置HSYNC引腳爲下降沿有效.我把JZ4776主控端配置成上升沿有效的時候,是獲取不了圖片的.既然廢棄了HSYNC行同步,那麼會不會出現行同步不一致而導致主控拒絕接收數據呢?個人認爲,有VSYNC足夠了,它引發了中斷,就意味着一幀圖像傳輸完畢,主控端就可以去處理數據了,HSYNC是可以被忽略的.如果遇到一些平臺比較嚴格的話,還需要處理HSYNC同步的話,就具體處理了.

        PCLK的極性如下:

  因此,我們可以確定HREF模式下PIN腳VSYNC、HREF(HSYNC)、PCLK的極性分別爲:

VSYNC:上升沿;
HERF(HSYNC):下降沿;
PCLK:上升沿.
  因此,再根據設備去配置主控端的相應極性:

  默認的VSYN和PCLK極性是一致的,主要是把HSP配置爲1(即下降沿有效).


 2-2.接收圖像的順序:

 一般CPU的CIM控制器都有從SENSOR端過來的接收到的數據進行重組排序處理的.一般而言,SENSOR端輸出的是YUV或RAW RGB,一般而言,數據手冊都可以找到明確其明確格式,比如OV9712的圖像輸出格式就是BAYER(RAW DATA)中的一種.從其數據手冊可以看到如下字樣:

The color filters are arranged in a Bayer pattern. The primary color BG/GR array is arranged in line-alternating fashion.
 「小技巧:」無論是YUV還是RAW DATA,如果是接收順序反了的話,一般都有輪廓.可以適當嘗試一下別的字節重組順序.

 JZ4775對從SENSOR接收過來的4個字節拼成32位的字,有下面8種方式:

   

 這裏選擇第五種方式,即3'b100.高低位調轉的方式.

    覈對了上述兩點之外,出來的圖像依然看不出圖像的完整性.配置依然可能存在問題,鏡頭也沒調焦距,上層轉換函數也有可能存在問題.這三個方面的因素都有可能導致同樣的現象.於是想了下有沒有更好更直接的快捷方式.通過查閱OV9712的數據手冊,發現其提供了個test pattern模式.進入這種模式下,顯示8段彩條.如下:


    在OV9712提供的另一款"應用程序編程手冊"可以知道進入test pattern模式通過下面寄存器設置:

  當然,還要設置寄存器0xca進入TestPattern模式.代碼如下:

void ov9712TestPattern(int iic_fd)
{
        iic_write(iic_fd,0xca,0x24);
        iic_write(iic_fd,0x12,0x02);
        iic_write(iic_fd,0x97,0x88);
}
  然後把SENSOR端過來的數據轉RGB565保存起來,發現圖片有斷層情況.後來檢查發現是轉換函數的bmp頭構造得有問題.修復後效果和test pattern一致.爲了調試方便,決定把轉換出來的RGB565(1280 X 800)顯示在2.8寸屏(320 x 240)上.通過跳行跳列實現.代碼如下:

/*
Function:
        Skip One Row And One Column.    
Date:
        2014-3-29
Author:
        SE7EN
*/
void skipPiexl1(const u16 *inBuf,u16 *outBuf,const u32 width,const u32 height,u32 div)
{
        assert((inBuf && outBuf && (0 == (width % 4) && (0 == (height % 4)) && (0 == (div % 4)))));

        const u16 *pInW = inBuf;
        u16 *pOut = outBuf;
        u32 i = 0,j = 0,k = 0,sum = 0,aver = 0;

        for(i = 0; i < height; i+=2)
        {
                for(j = 0; j < width; j+=2)
                {
                        *pOut = *pInW;
                        pOut++;
                        pInW +=2;
                }

                pInW = pInW + width;
        }
}
    因爲我的是豎屏,因此還需要把兩次縮放的像素buf旋轉90度,代碼如下:

/*
Function:
        Operation For RGB.
Date:
        2014-3-29
Author:
        SE7EN
*/

#include "skippiexl.h"
void rgb565_rotate90(const u16 *input, u16 *output,u32 width_in,u32 height_in)
{        
        const u16 *pIn=input;
        u16 *pOut=output;

        int i,j;

        for(i=0; i<height_in; i++)
        {
                for(j=0; j<width_in; j++)
                {
                        *pOut = *pIn++;
                        pOut = output+height_in*j + i;
                }
        }
}


3.小結:

 SENSOR其實是挺複雜的一個東西,很多過中涉及的概念都只是有個籠統的概念.在此作錄備忘,後續還需要調試圖像質量,這個只能靠技術支持了.

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章