📄 chg-pxa_ov_camera.c_bak
字号:
}
target_physical = (unsigned)buf_entry->paddr;
target_virtual = (unsigned)buf_entry->vaddr;
entry_size = buf_entry->size;
cur_node = cur_node->next;
}
if (remain_size > FIFO_1_SINGLE_DESC_TRANS_MAX)
des_transfer_size = FIFO_1_SINGLE_DESC_TRANS_MAX;
else
des_transfer_size = remain_size;
if (entry_size < des_transfer_size){
des_transfer_size = entry_size;
}
cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);
cur_des_virtual->dsadr = CIBR1_PHY; // FIFO1 physical address
cur_des_virtual->dtadr = target_physical;
cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;
if (u_last_virtual){
u_last_virtual->ddadr = (unsigned )cur_des_physical;
if (camera_context->capture_mode == CAPTURE_STILL_IMAGE)
u_last_virtual->ddadr |= 0x1;
u_last_virtual->dcmd |= DCMD_ENDIRQEN;
u_last_virtual = NULL;
}
// advance pointers
remain_size -= des_transfer_size;
entry_size -= des_transfer_size;
cur_des_virtual++;
cur_des_physical++;
target_physical += des_transfer_size;
camera_context->fifo1_num_descriptors ++;
desc_num ++;
}
last_des_virtual = cur_des_virtual - 1;
u_last_virtual = last_des_virtual;
//printk("%s: %d block %d u channel, desc_num=%d\n", __FUNCTION__, __LINE__, i, desc_num);
/* setup V Channel */
if (!camera_context->fifo2_descriptors_virtual){
camera_context->fifo2_descriptors_virtual = (unsigned)cur_des_virtual;
camera_context->fifo2_descriptors_physical = (unsigned)cur_des_physical;
}
remain_size = camera_context->fifo2_transfer_size;
while(remain_size){
if (desc_num >= camera_context->dma_descriptors_size){
printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);
return -ENOMEM;
}
if (entry_size == 0){
buf_entry = get_list_entry(cur_node);
if (!buf_entry){
printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);
return -ENOMEM;
}
target_physical = (unsigned)buf_entry->paddr;
target_virtual = (unsigned)buf_entry->vaddr;
entry_size = buf_entry->size;
cur_node = cur_node->next;
}
if (remain_size > FIFO_2_SINGLE_DESC_TRANS_MAX)
des_transfer_size = FIFO_2_SINGLE_DESC_TRANS_MAX;
else
des_transfer_size = remain_size;
if (entry_size < des_transfer_size){
des_transfer_size = entry_size;
}
cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);
cur_des_virtual->dsadr = CIBR2_PHY; // FIFO1 physical address
cur_des_virtual->dtadr = target_physical;
cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;
if (v_last_virtual){
v_last_virtual->ddadr = (unsigned)cur_des_physical;
if (camera_context->capture_mode == CAPTURE_STILL_IMAGE)
v_last_virtual->ddadr |= 0x1;
v_last_virtual->dcmd |= DCMD_ENDIRQEN;
v_last_virtual = NULL;
}
// advance pointers
remain_size -= des_transfer_size;
entry_size -= des_transfer_size;
cur_des_virtual++;
cur_des_physical++;
target_physical += des_transfer_size;
camera_context->fifo2_num_descriptors ++;
desc_num ++;
}
last_des_virtual = cur_des_virtual - 1;
v_last_virtual = last_des_virtual;
//printk("%s: %d block %d v channel, desc_num=%d\n", __FUNCTION__, __LINE__, i, desc_num);
}
y_last_virtual->ddadr = ((unsigned)camera_context->fifo0_descriptors_physical);
u_last_virtual->ddadr = ((unsigned)camera_context->fifo1_descriptors_physical);
v_last_virtual->ddadr = ((unsigned)camera_context->fifo2_descriptors_physical);
y_last_virtual->dcmd |= DCMD_ENDIRQEN;
if (camera_context->capture_mode == CAPTURE_STILL_IMAGE){
y_last_virtual->ddadr |= 0x1;
u_last_virtual->ddadr |= 0x1;
v_last_virtual->ddadr |= 0x1;
}
camera_context->fifo0_num_descriptors /= camera_context->block_number;
camera_context->fifo1_num_descriptors /= camera_context->block_number;
camera_context->fifo2_num_descriptors /= camera_context->block_number;
printk( "%s:%d Ysize=%d,Usize=%d,Vsize=%d,block_number=%d\n", \
__FUNCTION__, __LINE__,\
camera_context->fifo0_transfer_size,\
camera_context->fifo1_transfer_size, \
camera_context->fifo2_transfer_size,\
camera_context->block_number);
#if 0
// assume the blocks are stored consecutively
target_physical = (unsigned)p_ovcam_ctx->p_buffer_physical + p_ovcam_ctx->block_size * i;
target_virtual = (unsigned)p_ovcam_ctx->p_buffer_virtual + p_ovcam_ctx->block_size * i;
for(j=0; j<p_ovcam_ctx->fifo0_num_descriptors; j++)
{
// set descriptor
if (remain_size > SINGLE_DESCRIPTORS_TRANSFER_MAX)
des_transfer_size = SINGLE_DESCRIPTORS_TRANSFER_MAX;
else
des_transfer_size = remain_size;
cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);
cur_des_virtual->dsadr = CIBR0_PHY; // FIFO0 physical address
cur_des_virtual->dtadr = target_physical;
cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;
// advance pointers
remain_size -= des_transfer_size;
cur_des_virtual++;
cur_des_physical++;
target_physical += des_transfer_size;
target_virtual += des_transfer_size;
}
// stop the dma transfer on one frame captured
last_des_virtual = cur_des_virtual - 1;
//last_des_virtual->ddadr |= 0x1;
}
last_des_virtual->ddadr = ((unsigned)p_ovcam_ctx->fifo0_descriptors_physical);//LOOP
// generate fifo1 dma chains
if (p_ovcam_ctx->fifo1_transfer_size)
{
// record fifo1 descriptors' start address
p_ovcam_ctx->fifo1_descriptors_virtual = (unsigned)cur_des_virtual;
p_ovcam_ctx->fifo1_descriptors_physical = (unsigned)cur_des_physical;
for(i=0; i<p_ovcam_ctx->block_number; i++)
{
// in each iteration, generate one dma chain for one frame
remain_size = p_ovcam_ctx->fifo1_transfer_size;
// assume the blocks are stored consecutively
target_physical = (unsigned)p_ovcam_ctx->p_buffer_physical + p_ovcam_ctx->block_size * i
+ p_ovcam_ctx->fifo0_transfer_size;
target_virtual = (unsigned)p_ovcam_ctx->p_buffer_virtual + p_ovcam_ctx->block_size * i
+ p_ovcam_ctx->fifo0_transfer_size;
for(j=0; j<p_ovcam_ctx->fifo1_num_descriptors; j++)
{
// set descriptor
if (remain_size > SINGLE_DESCRIPTORS_TRANSFER_MAX)
{
des_transfer_size = SINGLE_DESCRIPTORS_TRANSFER_MAX;
}
else
{
des_transfer_size = remain_size;
}
cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);
cur_des_virtual->dsadr = CIBR1_PHY; // FIFO1 physical address
cur_des_virtual->dtadr = target_physical;
cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;
// advance pointers
remain_size -= des_transfer_size;
cur_des_virtual++;
cur_des_physical++;
target_physical += des_transfer_size;
target_virtual += des_transfer_size;
}
// stop the dma transfer on one frame captured
last_des_virtual = cur_des_virtual - 1;
//last_des_virtual->ddadr |= 0x1;
}
last_des_virtual->ddadr = ((unsigned)p_ovcam_ctx->fifo1_descriptors_physical);
}
// generate fifo2 dma chains
if (p_ovcam_ctx->fifo2_transfer_size)
{
// record fifo1 descriptors' start address
p_ovcam_ctx->fifo2_descriptors_virtual = (unsigned)cur_des_virtual;
p_ovcam_ctx->fifo2_descriptors_physical = (unsigned)cur_des_physical;
for(i=0; i<p_ovcam_ctx->block_number; i++)
{
// in each iteration, generate one dma chain for one frame
remain_size = p_ovcam_ctx->fifo2_transfer_size;
// assume the blocks are stored consecutively
target_physical = (unsigned)p_ovcam_ctx->p_buffer_physical + p_ovcam_ctx->block_size * i
+ p_ovcam_ctx->fifo0_transfer_size + p_ovcam_ctx->fifo1_transfer_size;
for(j=0; j<p_ovcam_ctx->fifo2_num_descriptors; j++)
{
// set descriptor
if (remain_size > SINGLE_DESCRIPTORS_TRANSFER_MAX)
{
des_transfer_size = SINGLE_DESCRIPTORS_TRANSFER_MAX;
}
else
{
des_transfer_size = remain_size;
}
cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);
cur_des_virtual->dsadr = CIBR2_PHY; // FIFO2 physical address
cur_des_virtual->dtadr = target_physical;
cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;
// 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 |= 0x1;
}
last_des_virtual->ddadr = ((unsigned)p_ovcam_ctx->fifo2_descriptors_physical);
}
#endif
ovcamprint("update_dma_chain( - ) \n");
return 0;
}
////////////////////////////////////////////////////////////////////////////////////
//Manual Set the DDADR and Start DMA transfer
////////////////////////////////////////////////////////////////////////////////////
void dma_transfer_start ( p_ovcamera_context_t p_ovcam_ctx, unsigned int block_id )
{
pxa_dma_desc *des_virtual, *des_physical;
int block_desc;
ovcamprint("dma_transfer_start( + ) \n");
if ( block_id >= p_ovcam_ctx->block_number)
{
return;
}
block_desc = p_ovcam_ctx->fifo0_num_descriptors + p_ovcam_ctx->fifo1_num_descriptors +\
p_ovcam_ctx->fifo2_num_descriptors;
// start channel 0
#if 0
des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_virtual
+ block_id * p_ovcam_ctx->fifo0_num_descriptors;
des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_physical
+ block_id * p_ovcam_ctx->fifo0_num_descriptors;
#endif
des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_virtual
+ block_id * block_desc;
des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_physical
+ block_id * block_desc;
DDADR(p_ovcam_ctx->dma_channels[0]) = des_physical;
DCSR(p_ovcam_ctx->dma_channels[0]) |= DCSR_RUN;
// start channel 1
if ( p_ovcam_ctx->fifo1_descriptors_virtual )
{
#if 0
des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_virtual +
block_id * p_ovcam_ctx->fifo1_num_descriptors;
des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_physical +
block_id * p_ovcam_ctx->fifo1_num_descriptors;
#endif
des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_virtual +
block_id * block_desc;
des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_physical +
block_id * block_desc;
DDADR(p_ovcam_ctx->dma_channels[1]) = des_physical;
DCSR(p_ovcam_ctx->dma_channels[1]) |= DCSR_RUN;
}
// start channel 2
if ( p_ovcam_ctx->fifo2_descriptors_virtual )
{
#if 0
des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_virtual +
block_id * p_ovcam_ctx->fifo2_num_descriptors;
des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_physical +
block_id * p_ovcam_ctx->fifo2_num_descriptors;
#endif
des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_virtual +
block_id * block_desc;
des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_physical +
block_id * block_desc;
DDADR(p_ovcam_ctx->dma_channels[2]) = des_physical;
DCSR(p_ovcam_ctx->dma_channels[2]) |= DCSR_RUN;
}
ovcamprint("dma_transfer_start( - ) \n");
}
void dma_transfer_stop ( p_ovcamera_context_t p_ovcam_ctx )
{
int ch0, ch1, ch2;
ovcamprint("dma_transfer_stop( + ) \n");
ch0 = p_ovcam_ctx->dma_channels[0];
ch1 = p_ovcam_ctx->dma_channels[1];
ch2 = p_ovcam_ctx->dma_channels[2];
DCSR(ch0) &= ~DCSR_RUN;
DCSR(ch1) &= ~DCSR_RUN;
DCSR(ch2) &= ~DCSR_RUN;
ovcamprint("dma_transfer_stop( - ) \n");
return;
}
static int capture_start ( p_ovcamera_context_t p_ovcam_ctx, unsigned int block_id, unsigned int frames )
{
int ret;
ovcamprint("capture_start( + ) \n");
ci_reset_fifo ();
ci_clear_int_status ( 0xFFFFFFFF );
g_camera_control.frames_captured = 0;
dma_transfer_start ( p_ovcam_ctx, block_id );
ret = p_ovcam_ctx->camera_functions->capture_start ( p_ovcam_ctx, frames );
ovcamprint("capture_start( - ) \n");
return ret;
}
static int ovcamera_init ( p_ovcamera_context_t p_ovcam_ctx )
{
int ret = 0;
int i;
ovcamprint("ovcamera_init ( + ) \n");
// parameter check
if (p_ovcam_ctx->p_buffer_virtual == NULL || p_ovcam_ctx->p_buffer_physical == NULL || p_ovcam_ctx->ui_buffer_size == 0)
{
ovcamprint("ovcamera_init ( -1 ) \n");
return STATUS_WRONG_PARAMETER;
}
if (p_ovcam_ctx->p_dmadest_virtual == NULL || p_ovcam_ctx->p_dmadest_physical == NULL ||
p_ovcam_ctx->ui_dmadest_size == 0)
{
ovcamprint("ovcamera_init ( -2 ) \n");
return STATUS_WRONG_PARAMETER;
}
if (p_ovcam_ctx->cf.in > CAMERA_IMAGE_FORMAT_MAX ||
p_ovcam_ctx->cf.out > CAMERA_IMAGE_FORMAT_MAX)
{
ovcamprint("ovcamera_init ( -4 ) \n");
return STATUS_WRONG_PARAMETER;
}
// check the function dispatch table according to the sensor type
if ( !p_ovcam_ctx->camera_functions )
{
ovcamprint("ovcamera_init ( -5 ) \n");
return STATUS_WRONG_PARAMETER;
}
if ( !p_ovcam_ctx->camera_functions->init ||
!p_ovcam_ctx->camera_functions->deinit ||
!p_ovcam_ctx->camera_functions->capture_set_format ||
!p_ovcam_ctx->camera_functions->capture_start ||
!p_ovcam_ctx->camera_functions->capture_stop )
{
ovcamprint("ovcamera_init ( -6 ) \n");
return STATUS_WRONG_PARAMETER;
}
// init context status
for(i=0; i<3; i++)
{
p_ovcam_ctx->dma_channels[i] = 0xFF;
}
(int)p_ovcam_ctx->fifo0_descriptors_virtual = NULL;
(int)p_ovcam_ctx->fifo1_descriptors_virtual = NULL;
(int)p_ovcam_ctx->fifo2_descriptors_virtual = NULL;
(int)p_ovcam_ctx->fifo0_descriptors_physical = NULL;
(int)p_ovcam_ctx->fifo1_descriptors_physical = NULL;
(int)p_ovcam_ctx->fifo2_descriptors_physical = NULL;
p_ovcam_ctx->fifo0_num_descriptors = 0;
p_ovcam_ctx->fifo1_num_descriptors = 0;
p_ovcam_ctx->fifo2_num_descriptors = 0;
p_ovcam_ctx->fifo0_transfer_size = 0;
p_ovcam_ctx->fifo1_transfer_size = 0;
p_ovcam_ctx->fifo2_transfer_size = 0;
p_ovcam_ctx->block_number = 0;
p_ovcam_ctx->block_size = 0;
p_ovcam_ctx->block_header = 0;
p_ovcam_ctx->block_tail = 0;
p_ovcam_ctx->block_header_t = 0;
p_ovcam_ctx->block_tail_t = 0;
// Enable hardware
ovcamerachip_gpio_init();
// capture interface init
ci_init();
// sensor init
ret = p_ovcam_ctx->camera_functions->init(p_ovcam_ctx);
if (ret)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -