📄 qci.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
#include <windows.h>
#include <ceddk.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <nkintr.h>
#include "monahans.h"
#include "qci.h"
#include "qci_private.h"
#include "BSP_CommonDefs.h"
#include "clkmgr.h"
//#include "ost.h"
#include "camera_SOC.h"
#include "CI.h"
#include "Args.h"
#include "ioctl_cfg.h"
#include "GPX_API.h"
#include "MFP_DRV.h"
static PXA_CLKREF_HANDLE g_hClock = NULL;
//PXA_CI_REGS* g_pCIRegs;
// to call back camera driver
typedef struct qci_callback_item_s
{
capture_callback_t callback;
ULONG user;
frame_t** frame;
} qci_callback_item_t;
static qci_callback_item_t callbacks[MAX_CALLBACK_NUM];
DWORD qci_sys_intr;
HANDLE qci_intr_event;
BOOL cgu_enable = 0;
dma_buf_t histogram_lut_buf;
int *histogram_lut_desc;
UINT32 histogram_lut_desc_phy;
char *lut = NULL;
#ifdef DEBUG
void QciDumpRegs();
#endif
static BOOL InitPins()
{
if (PXA_STATUS_SUCCESS != MFP_SetActiveMode(PXA_COMPONENT_CIF_ID))
{
RETAILMSG(1, (TEXT("CAM: Error Init MFP!\r\n")));
}
GPX_SetDirection(GPX_GPIO_UTMI_TEST_EN, PXA_GPIO_DIRECTION_OUT);
GPX_SetDirection(GPX_GPIO_UTMI_SWITCH, PXA_GPIO_DIRECTION_OUT);
GPX_SetDirection(GPX_GPIO_CAMERA_LIGHT_EN, PXA_GPIO_DIRECTION_OUT);
GPX_SetOutputLevel(GPX_GPIO_UTMI_TEST_EN, PXA_HI);
GPX_SetOutputLevel(GPX_GPIO_UTMI_SWITCH, PXA_LO);
/* Call_GPX */
GPX_SetDirection(GPX_GPIO_CAMERA_HI_PWDN, PXA_GPIO_DIRECTION_OUT);
GPX_SetDirection(GPX_GPIO_CAMERA_LO_PWDN, PXA_GPIO_DIRECTION_OUT);
GPX_SetOutputLevel(GPX_GPIO_CAMERA_HI_PWDN, PXA_HI);
GPX_SetOutputLevel(GPX_GPIO_CAMERA_LO_PWDN, PXA_HI);
return TRUE;
}
#define MFP_REG_SIZE 0x700
#define ci_reg_SIZE 0x400
static void HistogramLutInit()
{
UINT32 size;
dma_buf_t *buf = &histogram_lut_buf;
size = HISTOGRAM_LUT_BUF_SIZE + sizeof(PXA_CI_DMAC_DESCRIPTOR_T);
DMABufAlloc(buf, size, 0);
histogram_lut_desc = (int*)(buf->buf + HISTOGRAM_LUT_BUF_SIZE);
histogram_lut_desc_phy = buf->phy_addr + HISTOGRAM_LUT_BUF_SIZE;
}
static BOOL InitResources(void)
{
DWORD qci_irq = IRQ_QCI;
int status;
HANDLE thread;
g_pCIRegs = (PXA_CI_REGS*)PXA_CTX_GetRegAddr(PXA_PERIPHERAL_REGIDX_QCI);
g_hClock = PXA_CreateClockReferenceObject3(PXA_CKEN_CAMERA, PXA_CLKREF_ACCESS_EXCLUSIVE, FALSE);
status = KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &qci_irq, sizeof(UINT32),
&qci_sys_intr, sizeof(UINT32), NULL);
if (status != TRUE)
{
RETAILMSG(1, (TEXT("CAM: Error obtaining camera SYSINTR value %d!\n"), status));
return FALSE;
}
qci_intr_event = CreateEvent(NULL, FALSE, FALSE,NULL);
if (!InterruptInitialize(qci_sys_intr, qci_intr_event, NULL, 0))
{
RETAILMSG(1, (TEXT("CAM: Error initializing camera interrupt event!\n")));
return FALSE;
}
HistogramLutInit();
// Launch the Camera ISR
thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)QciIntrThread, 0, 0, NULL);
CloseHandle(thread);
return TRUE;
}
static BOOL LutLoad()
{
PXA_STATUS_T status;
if (lut)
{
status = PXA_CICGULoadLutRam(g_pCIRegs,
//ost_reg,
(UINT32*)histogram_lut_buf.buf,
histogram_lut_buf.phy_addr,
(UINT32*)histogram_lut_desc,
histogram_lut_desc_phy,
lut);
return status == PXA_STATUS_SUCCESS;
}
return FALSE;
}
static PXA_CI_IMAGE_FORMAT GetCIFormat(int format)
{
switch (format)
{
case PXA_CAMERA_IMAGE_FORMAT_RAW10:
return PXA_CI_RAW10;
case PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR:
return PXA_CI_YCBCR422_PLANAR;
default:
return PXA_CI_RAW10;
}
}
void QCIPowerOn()
{
UCHAR buffer[2];
InitPins();
QCIClockEnable(0);
// camera setup arava
//power on sensor
buffer[0] = 0x14;
buffer[1] = 0x2a;
I2C_WriteData(0x49, buffer, 2, TRUE, PXA_I2C_NORMAL_LEVEL);
}
void QCIClockEnable(BOOL is_on)
{
if((NULL != g_hClock)&& (is_on))
{
PXA_TurnOnClock(g_hClock);
PXA_CIInit(g_pCIRegs/*, clk_reg*/);
}
else
PXA_TurnOffClock(g_hClock);
}
BOOL QCIInitAll()
{
memset(callbacks, 0, sizeof(callbacks));
if (InitResources() != TRUE)
return FALSE;
//power_on();
QCIPowerOn();
return TRUE;
}
void QCISetInterface(qci_interface_t *intf)
{
// Configure CI according to OV2620's hardware
// master parallel with 8 data pins
PXA_CISetMode(g_pCIRegs, intf->mode, intf->data_width);
// enable pixel clock(sensor will provide pclock) and master clock = 26MHZ
PXA_CISetClock(g_pCIRegs,/* clk_reg, */TRUE, TRUE, intf->clock);
// data sample on rising and h,vsync active high
PXA_CISetPolarity(g_pCIRegs,
intf->pclk_polarity,
intf->hsync_polarity,
intf->vsync_polarity);
}
void QCIEnable()
{
PXA_CISetFIFO(g_pCIRegs, 0, PXA_CI_FIFO_THL_32, TRUE, TRUE);
PXA_CIEnable(g_pCIRegs);
}
void QCISetMasterTiming(qci_master_timing_t* timing)
{
PXA_CIConfigureMP(g_pCIRegs, timing->width, timing->height, &timing->timing);
}
// set qci input output format
void QCISetImageFormat(int in_format,
int out_format)
{
PXA_CI_CMU_USAGE cmu_usage = PXA_CI_CICMR_DMODE_DISABLE;
PXA_CI_IMAGE_FORMAT ci_in_format = GetCIFormat(in_format);
PXA_CI_IMAGE_FORMAT ci_out_format = GetCIFormat(out_format);
cgu_enable = 0;
PXA_CISetImageFormat(g_pCIRegs, ci_in_format, ci_out_format);
if (in_format == PXA_CAMERA_IMAGE_FORMAT_RAW10)
{
PXA_CICGUSetAddrMuxSelect(g_pCIRegs, PXA_CI_CGU_MUX_2_TO_9);
if (out_format == PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR)
{
cgu_enable = 1;
cmu_usage = PXA_CI_CMU_OUTPUT_YUV;
}
}
PXA_CICMUEnable(g_pCIRegs, cmu_usage);
}
void QCICaptureStart(int in_still_skips)
{
PXA_CIDisable(g_pCIRegs, /*ost_reg, */TRUE, TRUE);
PXA_CIResetFIFO(g_pCIRegs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -