⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image_sensor.c

📁 OV2640.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
    write_cmos_sensor(0x8C, 0x06);
    write_cmos_sensor(0x86, 0x35);
    write_cmos_sensor(0x50, 0x00);

    write_cmos_sensor(0x51, 0xCC);
    write_cmos_sensor(0x52, 0x99);

    write_cmos_sensor(0x53, 0x00);
    write_cmos_sensor(0x54, 0x00);
    write_cmos_sensor(0x55, 0x00);


    write_cmos_sensor(0x5A, 0xCC);
    write_cmos_sensor(0x5B, 0x99);
    write_cmos_sensor(0x5C, 0x00);
    write_cmos_sensor(0xD3, 0x82);

    write_cmos_sensor(0xE5, 0x1F);
    write_cmos_sensor(0xE1, 0x67);
    write_cmos_sensor(0xE0, 0x00);
    write_cmos_sensor(0xDD, 0x7F);
    write_cmos_sensor(0x05, 0x00);

    //write_cmos_sensor(0x87, 0xD0);
    write_cmos_sensor(0xC3, 0x81);
    write_cmos_sensor(0xC2, 0x01);
    write_cmos_sensor(0x92, 0x01);
    write_cmos_sensor(0x93, 0x00);
    write_cmos_sensor(0x92, 0x00);
    write_cmos_sensor(0x93, 0x00);
#else
    // setup sensor output ROI
    write_cmos_sensor(0x17, 0x10);
    write_cmos_sensor(0x18, 0x43);
    write_cmos_sensor(0x32, 0x36);
    write_cmos_sensor(0x19, 0x00);
    write_cmos_sensor(0x1A, 0x4D);
    write_cmos_sensor(0x03, 0x00);

    write_cmos_sensor(0x4F, 0xCA);  // 50Hz banding AEC 8 LSBs
    write_cmos_sensor(0x50, 0xA8);  // 60Hz banding AEC 8 LSBs
    write_cmos_sensor(0x5A, 0x23);  // 50/60Hz banding AEC maximum steps
    write_cmos_sensor(0x6D, 0x00);  // reserved
    write_cmos_sensor(0x3D, 0x38);  // PLL/divider setting
    write_cmos_sensor(0x39, 0x12);  // PWCOM1, reserved
    write_cmos_sensor(0x35, 0xDA);  // reserved
    iTemp = read_cmos_sensor(0x22); // ANCOM3
    write_cmos_sensor(0x22, iTemp | 0x10);
    write_cmos_sensor(0x37, 0xC3);  // reserved
    write_cmos_sensor(0x23, 0x00);  // reserved
    write_cmos_sensor(0x34, 0xC0);  // ARCOM2, reserved
    write_cmos_sensor(0x36, 0x1A);  // reserved
    write_cmos_sensor(0x06, 0x88);  // reserved
    write_cmos_sensor(0x07, 0xC0);  // reserved
    write_cmos_sensor(0x0D, 0x87);  // reserved
    write_cmos_sensor(0x0E, 0x41);  // reserved
    write_cmos_sensor(0x4C, 0x00);  // reserved
#endif

    gVGAmode = KAL_TRUE;

    if (pSensorConfigData->frame_rate == 0x0F) {   // MPEG4 Encode Mode
        MPEG4_encode_mode = KAL_TRUE;

#ifdef OV2640_MPEG4_QCIF_VIDEO_30FPS
        if (pImageWindow->image_target_width == 176 &&
            pImageWindow->image_target_height == 144) {
            // MT6228 supports QCIF MPEG4 up to 30fps 
            g_iOV2640_Mode = OV2640_MODE_QCIF_VIDEO;

            SET_TG_OUTPUT_CLK_DIVIDER(1);   // MCLK = 24MHz
            SET_CMOS_RISING_EDGE(0);
            SET_CMOS_FALLING_EDGE(1);
            SET_TG_PIXEL_CLK_DIVIDER(1);    // PCLK = 24MHz
            SET_CMOS_DATA_LATCH(1);

            //*******************************************
            // OV2640 clock calculation:
            // Fclk = (64 - 0x3D[5:0]) x MCLK / M, where
            //      Fclk: PLL output clock
            //      M = 2 if 0x3D[7:6] = 00
            //      M = 3 if 0x3D[7:6] = 01
            //      M = 4 if 0x3D[7:6] = 10
            //      M = 6 if 0x3D[7:6] = 11
            // Fint = Fclk / (2 x (0x11[5:0] + 1)), where
            //      Fint: internal clock
            // PCLK = Fint / 2
            //*******************************************
            write_cmos_sensor(PAGE_SETTING_REG, 0x01);
            write_cmos_sensor(0x3D, 0x38);
            write_cmos_sensor(0x11, 0x00);

//            iStartX = 4;
//            iStartY = 4;
            iDummyPixels = OV2640_VIDEO__QCIF_DUMMY_PIXELS;
            iDummyLines = 17; 
        }else {
#endif
            // MT6228 supports CIF MPEG4 up to 15fps 
            g_iOV2640_Mode = OV2640_MODE_CIF_VIDEO;

            /* config TG of ISP to match the setting of image sensor*/
            SET_TG_OUTPUT_CLK_DIVIDER(1);   // MCLK = 24MHz
            SET_CMOS_RISING_EDGE(0);
            SET_CMOS_FALLING_EDGE(1);
            SET_TG_PIXEL_CLK_DIVIDER(3);    // PCLK = 12MHz
            SET_CMOS_DATA_LATCH(1);

            //*******************************************
            // OV2640 clock calculation:
            // Fclk = (64 - 0x3D[5:0]) x MCLK / M, where
            //      Fclk: PLL output clock
            //      M = 2 if 0x3D[7:6] = 00
            //      M = 3 if 0x3D[7:6] = 01
            //      M = 4 if 0x3D[7:6] = 10
            //      M = 6 if 0x3D[7:6] = 11
            // Fint = Fclk / (2 x (0x11[5:0] + 1)), where
            //      Fint: internal clock
            // PCLK = Fint / 2
            //*******************************************
            write_cmos_sensor(PAGE_SETTING_REG, 0x01);
            write_cmos_sensor(0x3D, 0x38);
            write_cmos_sensor(0x11, 0x01);

//            iStartX = 4;
//            iStartY = 4;
            iDummyPixels = OV2640_VIDEO__CIF_DUMMY_PIXELS;
            iDummyLines = 0;
#ifdef OV2640_MPEG4_QCIF_VIDEO_30FPS
        }
#endif
    }else {
        MPEG4_encode_mode = KAL_FALSE;

        SET_TG_OUTPUT_CLK_DIVIDER(1);   // MCLK = 24MHz
        SET_CMOS_RISING_EDGE(0);
        SET_CMOS_FALLING_EDGE(1);
        SET_TG_PIXEL_CLK_DIVIDER(1);    // PCLK = 24MHz
        SET_CMOS_DATA_LATCH(1);

        //*******************************************
        // OV2640 clock calculation:
        // Fclk = (64 - 0x3D[5:0]) x MCLK / M, where
        //      Fclk: PLL output clock
        //      M = 2 if 0x3D[7:6] = 00
        //      M = 3 if 0x3D[7:6] = 01
        //      M = 4 if 0x3D[7:6] = 10
        //      M = 6 if 0x3D[7:6] = 11
        // Fint = Fclk / (2 x (0x11[5:0] + 1)), where
        //      Fint: internal clock
        // PCLK = Fint / 2
        //*******************************************
        write_cmos_sensor(PAGE_SETTING_REG, 0x01);
        write_cmos_sensor(0x3D, 0x38);
        write_cmos_sensor(0x11, 0x00);
        g_iPV_PCLK_Divider = ((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG) >> 4) & 0x0000000F) + 1;

//        iStartX = 4;
//        iStartY = 4+2;//remove top dummy line
        iDummyPixels = OV2640_PV_DUMMY_PIXELS;
        iDummyLines = 0; 

        g_iOV2640_Mode = OV2640_MODE_PREVIEW;
    }

    write_cmos_sensor(PAGE_SETTING_REG, 0x01);
    iTemp = read_cmos_sensor(0x04) & 0x2F;

    switch (pSensorConfigData->image_mirror) {
    case IMAGE_NORMAL:
        iStartX = 4;
        iStartY = 6;
        // do nothing
        break;

    case IMAGE_HV_MIRROR:
        iStartX = 4;
#ifdef OV_PROCESSING_RAW
        iStartY = 5;
        iTemp |= 0xC0;
#else
        iStartY = 4;
        iTemp |= 0xD0;
#endif
        break;

    default:
        ASSERT(0);
    }
    write_cmos_sensor(0x04, iTemp);

    // compensate OV2640 ABLC for every frame
    write_cmos_sensor(PAGE_SETTING_REG, 0x01);
    write_cmos_sensor(0x71, 0x94);  // reserved register

    OV2640_SetDummy(iDummyPixels, iDummyLines);

    g_iPreview_Column_Pixel = PV_PERIOD_PIXEL_NUMS + iDummyPixels;

    pImageWindow->grab_start_x = iStartX;
    pImageWindow->grab_start_y = iStartY;
    pImageWindow->exposure_window_width = IMAGE_SENSOR_PV_WIDTH;
    pImageWindow->exposure_window_height = IMAGE_SENSOR_PV_HEIGHT;

    write_OV2640_shutter(g_iExpLines);
}   /*  OV2640_Preview  */

void OV2640_Capture(image_sensor_exposure_window_struct *pImageWindow, image_sensor_config_struct *pSensorConfigData)
{
    kal_uint16 iCapture_Column_Pixel = 0, iShutter = g_iExpLines;
    kal_uint16 iDummyPixels = 0, iDummyLines = 0, iStartX, iStartY, iGrabWidth, iGrabHeight;
    kal_uint8 iTemp, iCP_PCLK_Div = 1;
    const kal_bool bMetaMode = pSensorConfigData->meta_mode != CAPTURE_MODE_NORMAL;

    if (pSensorConfigData->enable_shutter_tansfer == KAL_TRUE) {
        iShutter = pSensorConfigData->capture_shutter;
    }

    if ((pImageWindow->image_target_width <= IMAGE_SENSOR_PV_WIDTH) &&
        (pImageWindow->image_target_height <= IMAGE_SENSOR_PV_HEIGHT)) {
        gVGAmode = KAL_TRUE;

        if (pSensorConfigData->frame_rate == 0xF0) {    //  WEBCAM mode
            SET_TG_PIXEL_CLK_DIVIDER(1);    // PCLK = 24MHz
            SET_CMOS_DATA_LATCH(1);

            write_cmos_sensor(PAGE_SETTING_REG, 0x01);
            write_cmos_sensor(0x11, 0x00);
            iDummyPixels = 600; // to make line period same as preview
            iDummyLines = 0;

//            iStartX = 4;
//            iStartY = 4;
            iGrabWidth = IMAGE_SENSOR_PV_WIDTH;
            iGrabHeight = IMAGE_SENSOR_PV_HEIGHT - 20;
        }else {
            if (pImageWindow->digital_zoom_factor >= (ISP_DIGITAL_ZOOM_INTERVAL << 1) || bMetaMode == KAL_TRUE) {
                SET_TG_PIXEL_CLK_DIVIDER(7);    // PCLK = 6MHz
                SET_CMOS_DATA_LATCH(4);
                write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                write_cmos_sensor(0x11, 0x03);
                iDummyPixels = 70;
                iDummyLines = 0;
            }else { // capture < 2x digital zoom
                SET_TG_PIXEL_CLK_DIVIDER(3);    // PCLK = 12MHz
                SET_CMOS_DATA_LATCH(2);
                write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                write_cmos_sensor(0x11, 0x01);
                iDummyPixels = 0;
                iDummyLines = 0;
            }
//            iStartX = 4;
//            iStartY = 4;
            iGrabWidth = IMAGE_SENSOR_PV_WIDTH;
            iGrabHeight = IMAGE_SENSOR_PV_HEIGHT;
        }

        switch (pSensorConfigData->image_mirror) {
        case IMAGE_NORMAL:
            iStartX = 4;
#ifdef OV_PROCESSING_RAW
            iStartY = 6;
#else
            iStartY = 4;
#endif
            break;

        case IMAGE_HV_MIRROR:
            iStartX = 4;
#ifdef OV_PROCESSING_RAW
            iStartY = 5;
#else
            iStartY = 4;
#endif
        break;

        default:
            ASSERT(0);
        }

        iCapture_Column_Pixel = PV_PERIOD_PIXEL_NUMS + iDummyPixels;
        iCP_PCLK_Div = ((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG) >> 4) & 0x0000000F) + 1;
        iShutter = iShutter * g_iPreview_Column_Pixel / iCapture_Column_Pixel;
        iShutter = iShutter * g_iPV_PCLK_Divider / iCP_PCLK_Div;
    }else { // 2M UXGA Mode
        gVGAmode = KAL_FALSE;

#ifdef OV_PROCESSING_RAW
        /*Switch mode to 1610x1210*/
        write_cmos_sensor(PAGE_SETTING_REG,0x01);
        write_cmos_sensor(0x12, 0x00);  // switch to UXGA(1600x1200) mode

        // setup sensor output ROI
        write_cmos_sensor(0x17, 0x11);
        write_cmos_sensor(0x18, 0x76);
        write_cmos_sensor(0x32, 0x24);
        write_cmos_sensor(0x19, 0x01);
        write_cmos_sensor(0x1A, 0x99);
        write_cmos_sensor(0x03, 0x0E);

        write_cmos_sensor(0x4F, 0xBB);  // 50Hz banding AEC 8 LSBs
        write_cmos_sensor(0x50, 0x9C);  // 60Hz banding AEC 8 LSBs
        write_cmos_sensor(0x5A, 0x57);  // 50/60Hz banding AEC maximum steps
        write_cmos_sensor(0x6D, 0x80);  // reserved
//        write_cmos_sensor(0x3D, 0x34);  // PLL/divider setting
        write_cmos_sensor(0x3D, 0x38);  // PLL/divider setting

        write_cmos_sensor(0x39, 0x02);  // PWCOM1, reserved
        write_cmos_sensor(0x35, 0x88);  // reserved
        iTemp = read_cmos_sensor(0x22); // ANCOM3
        write_cmos_sensor(0x22, iTemp & 0xEF);

        write_cmos_sensor(0x37, 0x40);  // reserved
        write_cmos_sensor(0x23, 0x00);  // reserved
        write_cmos_sensor(0x34, 0xA0);  // ARCOM2, reserved
        write_cmos_sensor(0x36, 0x1A);  // reserved
        write_cmos_sensor(0x06, 0x02);  // reserved
        write_cmos_sensor(0x07, 0xC0);  // reserved
        write_cmos_sensor(0x0D, 0xB7);  // reserved
        write_cmos_sensor(0x0E, 0x01);  // reserved
        write_cmos_sensor(0x4C, 0x00);  // reserved

        write_cmos_sensor(PAGE_SETTING_REG, 0x00);
        write_cmos_sensor(0xC0, 0xCA);
        write_cmos_sensor(0xC1, 0x98);
        write_cmos_sensor(0x8C, 0x02);
        write_cmos_sensor(0x86, 0x35);
        write_cmos_sensor(0x50, 0x00);

        write_cmos_sensor(0x51, 0x94);
        write_cmos_sensor(0x52, 0x30);

        write_cmos_sensor(0x53, 0x00);
        write_cmos_sensor(0x54, 0x00);
        write_cmos_sensor(0x55, 0x88);
        write_cmos_sensor(0x57, 0x00);

        write_cmos_sensor(0x5A, 0x94);
        write_cmos_sensor(0x5B, 0x30);
        write_cmos_sensor(0x5C, 0x05);
        write_cmos_sensor(0xD3, 0x82);

        write_cmos_sensor(0xE5, 0x1F);
        write_cmos_sensor(0xE1, 0x67);
        write_cmos_sensor(0xE0, 0x00);
        write_cmos_sensor(0xDD, 0x7F);
        write_cmos_sensor(0x05, 0x00);

        write_cmos_sensor(0x87, OV_WPC_BPC_CTRL);

        write_cmos_sensor(0xC3, 0x01);
        write_cmos_sensor(0xC2, 0x81);
        write_cmos_sensor(0x92, 0x01);
        write_cmos_sensor(0x93, 0x00);
        write_cmos_sensor(0x92, 0x00);
        write_cmos_sensor(0x93, 0x00);
#else
        /*Switch mode to 1610x1210*/
        write_cmos_sensor(PAGE_SETTING_REG,0x01);
        write_cmos_sensor(0x12, 0x00);  // switch to UXGA(1600x1200) mode

        // setup sensor output ROI
        write_cmos_sensor(0x17, 0x11);
        write_cmos_sensor(0x18, 0x75);
        write_cmos_sensor(0x32, 0x3A);
        write_cmos_sensor(0x19, 0x01);
        write_cmos_sensor(0x1A, 0x98);
        write_cmos_sensor(0x03, 0x84);

        write_cmos_sensor(0x4F, 0xBB);  // 50Hz banding AEC 8 LSBs
        write_cmos_sensor(0x50, 0x9C);  // 60Hz banding AEC 8 LSBs
        write_cmos_sensor(0x5A, 0x57);  // 50/60Hz banding AEC maximum steps
        write_cmos_sensor(0x6D, 0x80);  // reserved
//        write_cmos_sensor(0x3D, 0x34);  // PLL/divider setting
        write_cmos_sensor(0x3D, 0x38);  // PLL/divider setting

        write_cmos_sensor(0x39, 0x02);  // PWCOM1, reserved
        write_cmos_sensor(0x35, 0x88);  // reserved
        iTemp = read_cmos_sensor(0x22); // ANCOM3
        write_cmos_sensor(0x22, iTemp & 0xEF);

        write_cmos_sensor(0x37, 0x40);  // reserved
        write_cmos_sensor(0x23, 0x00);  // reserved
        write_cmos_sensor(0x34, 0xA0);  // ARCOM2, reserved
        write_cmos_sensor(0x36, 0x1A);  // reserved
        write_cmos_sensor(0x06, 0x02);  // reserved
        write_cmos_sensor(0x07, 0xC0);  // reserved
        write_cmos_sensor(0x0D, 0xB7);  // reserved
        write_cmos_sensor(0x0E, 0x01);  // reserved
        write_cmos_sensor(0x4C, 0x00);  // reserved

#endif
        if ((pImageWindow->image_target_width <= IMAGE_SENSOR_FULL_WIDTH) &&
            (pImageWindow->image_target_height <= IMAGE_SENSOR_FULL_WIDTH)) {
            if (pImageWindow->digital_zoom_factor >= (ISP_DIGITAL_ZOOM_INTERVAL << 1) || bMetaMode == KAL_TRUE) {
                // capture >= 2x zoom
                if (bMetaMode == KAL_TRUE) {
                    SET_TG_PIXEL_CLK_DIVIDER(7);    // PCLK = 6MHz
                    SET_CMOS_DATA_LATCH(4);
                    write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                    write_cmos_sensor(0x11, 0x03);
                    iDummyPixels = 400;
                    iDummyLines = 0;
                }else {
                    SET_TG_PIXEL_CLK_DIVIDER(15);    // PCLK = 6MHz
                    SET_CMOS_DATA_LATCH(8);
                    write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                    write_cmos_sensor(0x11, 0x07);
                    iDummyPixels = 100;
                    iDummyLines = 0;
                }
            }else if (pImageWindow->digital_zoom_factor == ISP_DIGITAL_ZOOM_INTERVAL) {
                // capture w/o zoom
                SET_TG_PIXEL_CLK_DIVIDER(3);    // PCLK = 12MHz
                SET_CMOS_DATA_LATCH(2);
                write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                write_cmos_sensor(0x11, 0x01);
                iDummyPixels = 115;
                iDummyLines = 0;
            }else { // 1x < zoom factor < 2x
                SET_TG_PIXEL_CLK_DIVIDER(3);    // PCLK = 12MHz
                SET_CMOS_DATA_LATCH(2);
                write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                write_cmos_sensor(0x11, 0x01);
                iDummyPixels = 1725;
                iDummyLines = 0;
            }
        }else { // 3M capture mode
            if (pImageWindow->digital_zoom_factor >= (ISP_DIGITAL_ZOOM_INTERVAL << 1) || bMetaMode == KAL_TRUE) {
                SET_TG_PIXEL_CLK_DIVIDER(7);    // PCLK = 6MHz
                SET_CMOS_DATA_LATCH(4);
                write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                write_cmos_sensor(0x11, 0x03);
                iDummyPixels = 70;
                iDummyLines = 0;
            }else { // capture < 2x digital zoom
                SET_TG_PIXEL_CLK_DIVIDER(3);    // PCLK = 12MHz
                SET_CMOS_DATA_LATCH(2);
                write_cmos_sensor(PAGE_SETTING_REG, 0x01);
                write_cmos_sensor(0x11, 0x01);
                iDummyPixels = 0;
                iDummyLines = 0;
            }
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -