📄 chg-pxa_ov_camera.c
字号:
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; if(remain_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); } } if(camera_context->fifo0_transfer_size) y_last_virtual->ddadr = ((unsigned)camera_context->fifo0_descriptors_physical); if(camera_context->fifo1_transfer_size) u_last_virtual->ddadr = ((unsigned)camera_context->fifo1_descriptors_physical); if(camera_context->fifo2_transfer_size) v_last_virtual->ddadr = ((unsigned)camera_context->fifo2_descriptors_physical); y_last_virtual->dcmd |= DCMD_ENDIRQEN; if (camera_context->capture_mode == CAPTURE_STILL_IMAGE){ if(camera_context->fifo0_transfer_size) y_last_virtual->ddadr |= 0x1; if(camera_context->fifo1_transfer_size) u_last_virtual->ddadr |= 0x1; if(camera_context->fifo2_transfer_size) 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) { ovcamprint("ovcamera_init ( -7 ) \n"); goto camera_init_err; } //dma channels p_ovcam_ctx->dma_channels[0] = ci_dma_y; p_ovcam_ctx->dma_channels[1] = ci_dma_u; p_ovcam_ctx->dma_channels[2] = ci_dma_v; // set capture format ret = ovcamera_set_capture_format(p_ovcam_ctx); if (ret) { ovcamprint("ovcamera_init ( -8 ) \n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -