📄 xllp_camera.c
字号:
/******************************************************************************
** INTEL CONFIDENTIAL
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
** No 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. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
********************************************************************************/
#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_dmac.h"
#include "xllp_camera.h"
#include "xllp_camera_os_depend.h"
#include "xllp_ci.h"
#include "xllp_adcm2650.h"
/***********************************************************************
*
* Declarations
*
***********************************************************************/
#define SINGLE_DESCRIPTOR_TRANSFER_MAX 8000
static const XLLP_DMAC_DEVICE_T CAMERA_DMA_DEVICE[3] = { 68, 69, 70 };
// map of xllp camera image format (xllp_camera.h) ==> capture interface format (xllp_ci.h)
static const XLLP_CI_IMAGE_FORMAT FORMAT_MAPPINGS[] = {
XLLP_CI_RAW8, //RAW
XLLP_CI_RAW9,
XLLP_CI_RAW10,
XLLP_CI_RGB444, //RGB
XLLP_CI_RGB555,
XLLP_CI_RGB565,
XLLP_CI_RGB666_PACKED, //RGB Packed
XLLP_CI_RGB666,
XLLP_CI_RGB888_PACKED,
XLLP_CI_RGB888,
XLLP_CI_RGBT555_0, //RGB+Transparent bit 0
XLLP_CI_RGBT888_0,
XLLP_CI_RGBT555_1, //RGB+Transparent bit 1
XLLP_CI_RGBT888_1,
XLLP_CI_INVALID_FORMAT,
XLLP_CI_YCBCR422, //YCBCR
XLLP_CI_YCBCR422_PLANAR, //YCBCR Planaried
XLLP_CI_INVALID_FORMAT,
XLLP_CI_INVALID_FORMAT
};
static int PrvUpdateDMAChain( P_XLLP_Camera_Context_T camera_context );
static void PrvStartDMATransfer( P_XLLP_Camera_Context_T camera_context, unsigned block_id );
static void PrvStopDMATransfer( P_XLLP_Camera_Context_T camera_context );
static XLLP_STATUS_T PrvStartCapture( P_XLLP_Camera_Context_T camera_context, unsigned int block_id, unsigned int frames );
/***********************************************************************
*
* Private functions
*
***********************************************************************/
// Generate dma descriptors
// Pre-condition: these variables must be set properly
// block_number, fifox_transfer_size
// dma_descriptors_virtual, dma_descriptors_physical, dma_descirptors_size
// Post-condition: these variables will be set
// fifox_descriptors_virtual, fifox_descriptors_physical
// fifox_num_descriptors
int PrvUpdateDMAChain( P_XLLP_Camera_Context_T camera_context )
{
XLLP_DMAC_DESCRIPTOR_T *cur_des_virtual, *cur_des_physical, *last_des_virtual;
int des_transfer_size, remain_size;
unsigned int i,j;
XLLP_UINT32_T target_physical;
// clear descriptor pointers
camera_context->fifo0_descriptors_virtual = camera_context->fifo0_descriptors_physical = 0;
camera_context->fifo1_descriptors_virtual = camera_context->fifo1_descriptors_physical = 0;
camera_context->fifo2_descriptors_virtual = camera_context->fifo2_descriptors_physical = 0;
// calculate how many descriptors are needed per frame
camera_context->fifo0_num_descriptors = ( camera_context->fifo0_transfer_size + SINGLE_DESCRIPTOR_TRANSFER_MAX -1 )
/ SINGLE_DESCRIPTOR_TRANSFER_MAX;
camera_context->fifo1_num_descriptors = ( camera_context->fifo1_transfer_size + SINGLE_DESCRIPTOR_TRANSFER_MAX -1 )
/ SINGLE_DESCRIPTOR_TRANSFER_MAX;
camera_context->fifo2_num_descriptors = ( camera_context->fifo2_transfer_size + SINGLE_DESCRIPTOR_TRANSFER_MAX -1 )
/ SINGLE_DESCRIPTOR_TRANSFER_MAX;
// check if enough memory to generate descriptors
if ( (camera_context->fifo0_num_descriptors + camera_context->fifo1_num_descriptors + camera_context->fifo2_num_descriptors)
* camera_context->block_number > camera_context->dma_descriptors_size)
return -1;
// generate fifo0 dma chains
camera_context->fifo0_descriptors_virtual = (unsigned)camera_context->dma_descriptors_virtual;
camera_context->fifo0_descriptors_physical = (unsigned)camera_context->dma_descriptors_physical;
cur_des_virtual = (XLLP_DMAC_DESCRIPTOR_T*)camera_context->fifo0_descriptors_virtual;
cur_des_physical = (XLLP_DMAC_DESCRIPTOR_T*)camera_context->fifo0_descriptors_physical;
for(i=0; i<camera_context->block_number; i++) {
// in each iteration, generate one dma chain for one frame
remain_size = camera_context->fifo0_transfer_size;
// assume the blocks are stored consecutively
target_physical = (unsigned)camera_context->buffer_physical + camera_context->block_size * i;
for(j=0; j<camera_context->fifo0_num_descriptors; j++) {
// set descriptor
if (remain_size > SINGLE_DESCRIPTOR_TRANSFER_MAX)
des_transfer_size = SINGLE_DESCRIPTOR_TRANSFER_MAX;
else
des_transfer_size = remain_size;
cur_des_virtual->DDADR = (unsigned)cur_des_physical + sizeof(XLLP_DMAC_DESCRIPTOR_T);
cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR0; // FIFO0 physical address
cur_des_virtual->DTADR = target_physical;
cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_16 << 16);
// advance pointers
remain_size -= des_transfer_size;
cur_des_virtual++;
cur_des_physical++;
target_physical += des_transfer_size;
}
// stop the dma transfer on one frame captured
last_des_virtual = cur_des_virtual - 1;
}
last_des_virtual->DDADR = ((unsigned)camera_context->fifo0_descriptors_physical);
// generate fifo1 dma chains
if (camera_context->fifo1_transfer_size) {
// record fifo1 descriptors' start address
camera_context->fifo1_descriptors_virtual = (unsigned)cur_des_virtual;
camera_context->fifo1_descriptors_physical = (unsigned)cur_des_physical;
for(i=0; i<camera_context->block_number; i++) {
// in each iteration, generate one dma chain for one frame
remain_size = camera_context->fifo1_transfer_size;
// assume the blocks are stored consecutively
target_physical = (unsigned)camera_context->buffer_physical + camera_context->block_size * i
+ camera_context->fifo0_transfer_size;
for(j=0; j<camera_context->fifo1_num_descriptors; j++) {
// set descriptor
if (remain_size > SINGLE_DESCRIPTOR_TRANSFER_MAX)
des_transfer_size = SINGLE_DESCRIPTOR_TRANSFER_MAX;
else
des_transfer_size = remain_size;
cur_des_virtual->DDADR = (unsigned)cur_des_physical + sizeof(XLLP_DMAC_DESCRIPTOR_T);
cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR1; // FIFO1 physical address
cur_des_virtual->DTADR = target_physical;
cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_8 << 16);
// advance pointers
remain_size -= des_transfer_size;
cur_des_virtual++;
cur_des_physical++;
target_physical += des_transfer_size;
}
// stop the dma transfer on one frame captured
last_des_virtual = cur_des_virtual - 1;
}
last_des_virtual->DDADR = ((unsigned)camera_context->fifo1_descriptors_physical);
}
// generate fifo2 dma chains
if (camera_context->fifo2_transfer_size) {
// record fifo1 descriptors' start address
camera_context->fifo2_descriptors_virtual = (unsigned)cur_des_virtual;
camera_context->fifo2_descriptors_physical = (unsigned)cur_des_physical;
for(i=0; i<camera_context->block_number; i++) {
// in each iteration, generate one dma chain for one frame
remain_size = camera_context->fifo2_transfer_size;
// assume the blocks are stored consecutively
target_physical = (unsigned)camera_context->buffer_physical + camera_context->block_size * i
+ camera_context->fifo0_transfer_size + camera_context->fifo1_transfer_size;
for(j=0; j<camera_context->fifo2_num_descriptors; j++) {
// set descriptor
if (remain_size > SINGLE_DESCRIPTOR_TRANSFER_MAX)
des_transfer_size = SINGLE_DESCRIPTOR_TRANSFER_MAX;
else
des_transfer_size = remain_size;
cur_des_virtual->DDADR = (unsigned)cur_des_physical + sizeof(XLLP_DMAC_DESCRIPTOR_T);
cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR2; // FIFO2 physical address
cur_des_virtual->DTADR = target_physical;
cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_8 << 16);
// advance pointers
remain_size -= des_transfer_size;
cur_des_virtual++;
cur_des_physical++;
target_physical += des_transfer_size;
}
// stop the dma transfer on one frame captured
last_des_virtual = cur_des_virtual - 1;
}
last_des_virtual->DDADR = ((unsigned)camera_context->fifo2_descriptors_physical);
}
return 0;
}
void PrvStartDMATransfer( P_XLLP_Camera_Context_T camera_context, unsigned block_id )
{
XLLP_DMAC_DESCRIPTOR_T *des_virtual, *des_physical;
if (block_id >= camera_context->block_number)
return;
// start channel 0
des_virtual = (P_XLLP_DMAC_DESCRIPTOR_T)camera_context->fifo0_descriptors_virtual + block_id * camera_context->fifo0_num_descriptors;
des_physical = (P_XLLP_DMAC_DESCRIPTOR_T)camera_context->fifo0_descriptors_physical + block_id * camera_context->fifo0_num_descriptors;
OS_DmaCfgChannelDescTransfer( des_virtual,
des_physical,
camera_context->dma_channels[0],
CAMERA_DMA_DEVICE[0],
XLLP_DMAC_ALIGNMENT_OFF
);
OS_DmaStartTransfer( camera_context->dma_channels[0] );
// start channel 1
if ( camera_context->fifo1_descriptors_virtual ) {
des_virtual = (P_XLLP_DMAC_DESCRIPTOR_T)camera_context->fifo1_descriptors_virtual + block_id * camera_context->fifo1_num_descriptors;
des_physical = (P_XLLP_DMAC_DESCRIPTOR_T)camera_context->fifo1_descriptors_physical + block_id * camera_context->fifo1_num_descriptors;
OS_DmaCfgChannelDescTransfer( des_virtual,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -