adcm2650.c

来自「该BSP是基于PXA270+WINCE的BSP」· C语言 代码 · 共 244 行

C
244
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
/****************************************************************************** 
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.  
** Title to the Material remains with Intel Corporation or its suppliers and licensors. 
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.  
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise 
** Some portion of the Materials may be copyrighted by Microsoft Corporation.
**
********************************************************************************/

#include "xllp_defs.h"
#include "xllp_serialization.h"
#include "xllp_bcr.h"
#include "xllp_clkmgr.h"
#include "xllp_ost.h"
#include "xllp_gpio.h"
#include "xllp_camera.h"
#include "xllp_ci.h"
#include "adcm2650.h"
#include "adcm2650_hw.h"


/***********************************************************************
 *
 * ADCM2650 Functions
 *
 ***********************************************************************/
XLLP_STATUS_T CameraFuncADCM2650Init(  P_XLLP_Camera_Context_T camera_context )
{
    XLLP_UINT8_T sensor_rev;
    XLLP_UINT16_T cm_rev, regv;
    int status;
    P_XLLP_BCR_T    pbcr;

    // Configure CI according to ADCM2650's hardware        
    // master parallel with 8 data pins
    XllpCISetMode(camera_context->ci_reg_base, XLLP_CI_MODE_MP, XLLP_CI_DATA_WIDTH8);
    
    // enable pixel clock(sensor will provide pclock) and master clock = 5.60MHZ
    XllpCISetClock(camera_context->ci_reg_base, camera_context->clk_reg_base, XLLP_TRUE, XLLP_TRUE, 560); // 5.60MHz

    // data sample on rising and h,vsync active high
    XllpCISetPolarity(camera_context->ci_reg_base, XLLP_FALSE, XLLP_FALSE, XLLP_FALSE);
    
    // fifo control
    XllpCISetFIFO(camera_context->ci_reg_base, 1000, XLLP_CI_FIFO_THL_32, XLLP_TRUE, XLLP_TRUE);

    // ADCM2650 Power on sequence
    // 1 Turn on M_VCC and wait for 20 ms.
    // initilization on Board Level
    // In MiscWrite Reg1(Phys Addr: 0x0800_0080):
    //   Bit 15: CAMERA_ON (1:On  0: Off)
    //   Bit 14: CAMERA_SEL (1:Routed to Camera Interface  0: To SSP1, USIM, PWM1)
    pbcr = (P_XLLP_BCR_T)camera_context->board_reg_base;
    pbcr->MISCWR1 |= 0x3 << 14;
    XllpOstDelayMilliSeconds((P_XLLP_OST_T)camera_context->ost_reg_base, 20);

    // 2 Turn on M_CLK using xx MHz and wait for 150 ms.
    XllpCIEnable(camera_context->ci_reg_base, XLLP_TRUE);
    XllpOstDelayMilliSeconds((P_XLLP_OST_T)camera_context->ost_reg_base, 150);

    // read out version
    status = ADCM2650VersionRevision(&cm_rev, &sensor_rev);
    if (cm_rev != PIPE_REV || sensor_rev != SENSOR_REV) 
        return XLLP_STATUS_FAILURE;

    // power on the module
    // note: pll is enabled, ADCM is not using external clock.  This frequency setting does nothing when using the PLL.
    status = ADCM2650PowerOn(7); // external mclk = 7MHZ 
    
    // set default output format
    status = ADCM2650SwitchToNormal(VIEWFINDER_MODE);
    status = ADCM2650SwitchToNormal(STILLFRAME_MODE);
    status = ADCM2650ViewfinderCfgOutput(O_FORMAT_422_B_YCbYCr);
    status = ADCM2650StillFrameCfgOutput(O_FORMAT_422_B_YCbYCr);

    // clear video sub-sampling and set v-mirror and h-mirror
    status = ADCM2650PipelineRead(VIDEO_CONFIG, &regv); 
    regv &= ~VIDEO_CONFIG_SS;    
    regv &= ~(VIDEO_CONFIG_V_MIRROR | VIDEO_CONFIG_H_MIRROR);  

    ADCM2650PipelineWrite(VIDEO_CONFIG, regv);

//  testing only
//	ADCM2650PipelineWrite(TCTRL_VID, 0x0u << 6 | 0x8); // slow down the pixel output to match our MCLK
//	ADCM2650PipelineWrite(T_DGEN_M, 0x1 | (0x4u<<3) | (0x1u<<6) ); // all white test image
//	ADCM2650PipelineWrite(T_DGEN_M, 0x7 | (0x4u<<3) | (0x1u<<6) ); // color bars
//	ADCM2650PipelineWrite(T_DGEN_M, 0x5 | (0x4u<<3) | (0x1u<<6) ); // checker board
//	ADCM2650PipelineWrite(T_DGEN_M, 0x6 | (0x4u<<3) | (0x1u<<6) ); // diagonal resolution chart


	// gives 34 fps QCIF
	ADCM2650PipelineRead(PLL_CTRL_1, &regv);
	ADCM2650PipelineWrite(PLL_CTRL_1, 0x4848);
	ADCM2650PipelineRead(PLL_CTRL_2, &regv);
	ADCM2650PipelineWrite(PLL_CTRL_2, 0x9010);
	ADCM2650PipelineWrite(CMD_2, 0x0300);

/*
	// gives 40fps QCIF with some noise
	ADCM2650PipelineRead(PLL_CTRL_1, &regv);
	ADCM2650PipelineWrite(PLL_CTRL_1, 0x4F07);
	ADCM2650PipelineRead(PLL_CTRL_2, &regv);
	ADCM2650PipelineWrite(PLL_CTRL_2, 0x2703);
	ADCM2650PipelineWrite(CMD_2, 0x0300);
*/
    return XLLP_STATUS_SUCCESS;
}

XLLP_STATUS_T CameraFuncADCM2650DeInit(  P_XLLP_Camera_Context_T camera_context )
{
    P_XLLP_BCR_T    pbcr;

    // power off the external module
    ADCM2650PowerOff(); 

    // disable CI
    XllpCIDisable(camera_context->ci_reg_base, camera_context->ost_reg_base, XLLP_TRUE, XLLP_TRUE);      // quick disable

    // cut down at Board Level
    pbcr = (P_XLLP_BCR_T)camera_context->board_reg_base;
    pbcr->MISCWR1 &= ~(0x3 << 14);
    return XLLP_STATUS_SUCCESS;
}

XLLP_STATUS_T CameraFuncADCM2650SetCaptureFormat(  P_XLLP_Camera_Context_T camera_context )
{
    ADCM_WINDOWSIZE wsize;
    XLLP_UINT16_T adcm_format, regv;
    int status;
//	XLLP_UINT8_T fwrow, fwcol, lwrow, lwcol;

    // set sensor input/output window
    wsize.width = camera_context->capture_width;
    wsize.height = camera_context->capture_height;
    ADCM2650ViewfinderInputSize(&wsize);
    ADCM2650ViewfinderOutputSize(&wsize);
 	ADCM2650StillframeInputSize(&wsize);
	ADCM2650StillframeOutputSize(&wsize);

/*
	fwrow = (((640 - wsize.height) / 2) + 4) / 4;
	fwcol = (((480 - wsize.width ) / 2) + 24) / 4;
	lwrow = (((640 - wsize.height) / 2) + wsize.height + 24 ) / 4;
	lwcol = (((480 - wsize.width ) / 2) + wsize.width + 44 ) / 4;
	
	ADCM2650SensorWriteWS(FWROW, fwrow);
	ADCM2650SensorWriteWS(FWCOL, fwcol);
	ADCM2650SensorWriteWS(LWROW, lwrow);
	ADCM2650SensorWriteWS(LWCOL, lwcol);
*/

    // set sensor format
    switch(camera_context->capture_input_format) {
        case XLLP_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR:
        case XLLP_CAMERA_IMAGE_FORMAT_YCBCR422_PACKED:
            adcm_format = O_FORMAT_422_B_YCbYCr;
            break;
        case XLLP_CAMERA_IMAGE_FORMAT_RGB565:
            adcm_format = O_FORMAT_565_RGB;
            break;
        case XLLP_CAMERA_IMAGE_FORMAT_RGB888_PACKED:
        case XLLP_CAMERA_IMAGE_FORMAT_RGB888_PLANAR:
            adcm_format = O_FORMAT_888RGB;
            break;
        default:
            adcm_format = O_FORMAT_422_B_YCbYCr;
            break;
    }
    ADCM2650ViewfinderCfgOutput(adcm_format);
    ADCM2650StillFrameCfgOutput(adcm_format);

    // set video v-mirror and h-mirror bits
    status = ADCM2650PipelineRead(VIDEO_CONFIG, &regv); 
    
    regv &= ~(VIDEO_CONFIG_V_MIRROR | VIDEO_CONFIG_H_MIRROR);   
    if ( camera_context->sensor_flip_mode & XLLP_CAMERA_VIDEO_FLIP_VERTICAL )
        regv |= VIDEO_CONFIG_V_MIRROR;

    if ( camera_context->sensor_flip_mode & XLLP_CAMERA_VIDEO_FLIP_HORIZONTAL )
        regv |= VIDEO_CONFIG_H_MIRROR;
    
    ADCM2650PipelineWrite(VIDEO_CONFIG, regv);

    // set still image v-mirror and h-mirror bits
    status = ADCM2650PipelineRead(STILL_CONFIG, &regv); 
    
    regv &= ~(STILL_CONFIG_V_MIRROR | STILL_CONFIG_H_MIRROR);   
    if ( camera_context->sensor_flip_mode & XLLP_CAMERA_STILL_FLIP_VERTICAL )
        regv |= STILL_CONFIG_V_MIRROR;

    if ( camera_context->sensor_flip_mode & XLLP_CAMERA_STILL_FLIP_HORIZONTAL )
        regv |= STILL_CONFIG_H_MIRROR;
    
    ADCM2650PipelineWrite(STILL_CONFIG, regv);


    return XLLP_STATUS_SUCCESS;
}

XLLP_STATUS_T CameraFuncADCM2650StartCapture(  P_XLLP_Camera_Context_T camera_context, unsigned int frames )
{   
    // frames=0 means continues capture
    if (frames == 0) {
        // set viewfinder to infinite output
        ADCM2650ResumetoFullOutputMode();
        ADCM2650ViewfinderOn();
    }
    else {
        // halt viewfinder output
        ADCM2650HaltVideoOutput();
        // limit output frames
        ADCM2650PipelineWrite(UART_CREDITS, frames);
    }

    // turn viewfinder on
    ADCM2650ViewfinderOn();
    return XLLP_STATUS_SUCCESS;
}

XLLP_STATUS_T CameraFuncADCM2650StopCapture(  P_XLLP_Camera_Context_T camera_context )
{
    ADCM2650ViewfinderOff();
    XllpOstDelayMilliSeconds((P_XLLP_OST_T)camera_context->ost_reg_base, 200);
    return XLLP_STATUS_SUCCESS;
}

⌨️ 快捷键说明

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