⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pxa27x_camera.c

📁 该BSP是基于PXA270+WINCE的BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
                    cur_des_virtual->DTADR = (unsigned)pDescriptorInfo->pBufferPhyAddress[k++];
                    cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_16 << 16);
	    
                    if (j == 0)
                    {
                            pDescriptorInfo->pPhysAddr_X1_CH0 = (XLLP_UINT32_T)pDescriptorInfo->pDescriptorBufferPhyAddress[l-1];// Physical address of the first real descriptor
                    }
                    // Special case for the last non-phantom descriptor in the chain
                    // Enable an end of frame interrupt for this descriptor only.
                    // Save a pointer to this descriptor and reset the remaining size for the phantom descriptor chain
                    if (j == ((fifo0_num_descriptors >> 1) - 1))
                    {
                            cur_des_virtual->DCMD |= XLLP_DMAC_DCMD_END_IRQ_EN;
                            pDescriptorInfo->pVirtAddr_Xn_CH0 = (XLLP_UINT32_T)cur_des_virtual;// Virtual address of the last real descriptor
                            // Reset the DMA transfer size for the phantom descriptor
                            remain_size = fifo0_transfer_size;
                    }
            } else
            // Build the phantom DMA chain
            {
                    cur_des_virtual->DDADR = (unsigned)pDescriptorInfo->pDescriptorBufferPhyAddress[++l];
                    cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR0;                      // FIFO0 physical address
                    cur_des_virtual->DTADR = (unsigned)pDescriptorInfo->pPhysAddr_Phantom;
                    cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_16 << 16);
            
                    if (j == 0)
                    {
                            pDescriptorInfo->pPhysAddr_XP1_CH0 = (XLLP_UINT32_T)pDescriptorInfo->pDescriptorBufferPhyAddress[l-1];          // Physical address of the first phantom descriptor
                    }
                    if (j == ((fifo0_num_descriptors >> 1) - 1))
                    {
                            pDescriptorInfo->pVirtAddr_XPn_CH0 = (XLLP_UINT32_T)cur_des_virtual;    // Virtual address of the last phantom descriptor       
                    }
            }
            // advance pointers
            remain_size -= des_transfer_size;
            cur_des_virtual++;
        }
    }
    
    // generate fifo1 dma chains
    if (fifo1_transfer_size) {

        for(i=0; i < 2; i++) {
            // in each iteration, generate one dma chain for one frame
            remain_size = fifo1_transfer_size;
        
            for(j=0; j < fifo1_num_descriptors >> 1; j++) {
                // set descriptor
                if (remain_size > SINGLE_DESCRIPTOR_TRANSFER_MAX) 
                    des_transfer_size = SINGLE_DESCRIPTOR_TRANSFER_MAX;
                else
                    des_transfer_size = remain_size;

                if (i == 0)
                {
                        cur_des_virtual->DDADR = (unsigned)pDescriptorInfo->pDescriptorBufferPhyAddress[++l];
                        cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR1;      // FIFO1 physical address
                        cur_des_virtual->DTADR = (unsigned)pDescriptorInfo->pBufferPhyAddress[k++];
                        cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_8 << 16);
                
                        if (j == 0)
                                pDescriptorInfo->pPhysAddr_X1_CH1 = (XLLP_UINT32_T)pDescriptorInfo->pDescriptorBufferPhyAddress[l-1];// Physical address of the first real descriptor
                        if (j == ((fifo1_num_descriptors >> 1) - 1))
                        {
                                pDescriptorInfo->pVirtAddr_Xn_CH1 = (XLLP_UINT32_T)cur_des_virtual;// Virtual address of the last real descriptor
		
                                // Reset the DMA transfer size for the phantom descriptor
                                remain_size = fifo1_transfer_size;
                        }
                }
                else 
                {
                        cur_des_virtual->DDADR = (unsigned)pDescriptorInfo->pDescriptorBufferPhyAddress[++l];
                        cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR1;      // FIFO1 physical address
                        cur_des_virtual->DTADR = (unsigned)pDescriptorInfo->pPhysAddr_Phantom;
                        cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_8 << 16);
                        
                        if (j == 0)
                                pDescriptorInfo->pPhysAddr_XP1_CH1 = (XLLP_UINT32_T)pDescriptorInfo->pDescriptorBufferPhyAddress[l-1];          // Physical address of the first phantom descriptor
                        if (j == ((fifo1_num_descriptors >> 1) - 1))
                                pDescriptorInfo->pVirtAddr_XPn_CH1 = (XLLP_UINT32_T)cur_des_virtual;    // Virtual address of the last phantom descriptor       
                }

                // advance pointers
                remain_size -= des_transfer_size;
                cur_des_virtual++;
            }
        }
    }

    // generate fifo2 dma chains
    if (fifo2_transfer_size) {

        for(i=0; i < 2; i++) {
            // in each iteration, generate one dma chain for one frame
            remain_size = fifo2_transfer_size;
    
            for(j=0; j < fifo2_num_descriptors >> 1; j++) {
                // set descriptor
                if (remain_size > SINGLE_DESCRIPTOR_TRANSFER_MAX) 
                    des_transfer_size = SINGLE_DESCRIPTOR_TRANSFER_MAX;
                else
                    des_transfer_size = remain_size;

                if (i == 0)
                {
                        cur_des_virtual->DDADR = (unsigned)pDescriptorInfo->pDescriptorBufferPhyAddress[++l];
                        cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR2;      // FIFO2 physical address
                        cur_des_virtual->DTADR = (unsigned)pDescriptorInfo->pBufferPhyAddress[k++];
                        cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_8 << 16);
		
                        if (j == 0)
                                pDescriptorInfo->pPhysAddr_X1_CH2 = (XLLP_UINT32_T)pDescriptorInfo->pDescriptorBufferPhyAddress[l-1];// Physical address of the first real descriptor
                        if (j == ((fifo2_num_descriptors >> 1) - 1))
                        {
                                pDescriptorInfo->pVirtAddr_Xn_CH2 = (XLLP_UINT32_T)cur_des_virtual;// Virtual address of the last real descriptor
		
                                // Reset the DMA transfer size for the phantom descriptor
                                remain_size = fifo2_transfer_size;
                        }
		
                }
                else
                {
                        cur_des_virtual->DDADR = (unsigned)pDescriptorInfo->pDescriptorBufferPhyAddress[++l];
                        cur_des_virtual->DSADR = XLLP_CI_REGBASE_PHY + XLLP_CIBR2;      // FIFO2 physical address
                        cur_des_virtual->DTADR = (unsigned)pDescriptorInfo->pPhysAddr_Phantom;
                        cur_des_virtual->DCMD = des_transfer_size | XLLP_DMAC_DCMD_FLOW_SRC | XLLP_DMAC_DCMD_INC_TRG_ADDR | (XLLP_DMAC_BURSTSIZE_8 << 16);
        	
                        if (j == 0)
                                pDescriptorInfo->pPhysAddr_XP1_CH2 = (XLLP_UINT32_T)pDescriptorInfo->pDescriptorBufferPhyAddress[l-1];          // Physical address of the first phantom descriptor
                        if (j == ((fifo2_num_descriptors >> 1) - 1))
                                pDescriptorInfo->pVirtAddr_XPn_CH2 = (XLLP_UINT32_T)cur_des_virtual;    // Virtual address of the last phantom descriptor       
		
                }
                // advance pointers
                remain_size -= des_transfer_size;
                cur_des_virtual++;
            }
        }
    }
    return TRUE;   
}


/***********************************************************************
 *
 * Private functions
 *
 ***********************************************************************/
void PrvStartDMATransfer(P_HW_CONTEXT_T pHwContext, unsigned block_id)
{
    XLLP_DMAC_DESCRIPTOR_T *des_virtual, *des_physical;


    des_virtual = (P_XLLP_DMAC_DESCRIPTOR_T)NULL;
    des_physical = (P_XLLP_DMAC_DESCRIPTOR_T)pHwContext->XllpDMA.fifo0_descriptors_physical;
    XllpDmacCfgChannelDescTransfer( //des_virtual,
                               des_physical,
                               pHwContext->XllpDMA.dma_channels[0],        
                               CAMERA_DMA_DEVICE[0],                    
                               XLLP_DMAC_ALIGNMENT_OFF              
                              );

    if ( pHwContext->XllpDMA.fifo1_transfer_size ) {
                des_virtual = (P_XLLP_DMAC_DESCRIPTOR_T)NULL;
                des_physical = (P_XLLP_DMAC_DESCRIPTOR_T)pHwContext->XllpDMA.fifo1_descriptors_physical;
                XllpDmacCfgChannelDescTransfer( //des_virtual,
                                   des_physical,
                                   pHwContext->XllpDMA.dma_channels[1],        
                                   CAMERA_DMA_DEVICE[1],                    
                                   XLLP_DMAC_ALIGNMENT_OFF              
                                  );
        }

    if ( pHwContext->XllpDMA.fifo2_transfer_size ) {
        des_virtual = (P_XLLP_DMAC_DESCRIPTOR_T)NULL;
        des_physical = (P_XLLP_DMAC_DESCRIPTOR_T)pHwContext->XllpDMA.fifo2_descriptors_physical;
        XllpDmacCfgChannelDescTransfer( //des_virtual,
                                   des_physical,
                                   pHwContext->XllpDMA.dma_channels[2],        
                                   CAMERA_DMA_DEVICE[2],                    
                                   XLLP_DMAC_ALIGNMENT_OFF              
                                  );
    }

    if ( pHwContext->XllpDMA.fifo0_transfer_size &&
         pHwContext->XllpDMA.fifo1_transfer_size &&
         pHwContext->XllpDMA.fifo2_transfer_size ) 
    {
        XllpDmacStartTransfer( pHwContext->XllpDMA.dma_channels[0] );
        XllpDmacStartTransfer( pHwContext->XllpDMA.dma_channels[1] );
        XllpDmacStartTransfer( pHwContext->XllpDMA.dma_channels[2] );
    } else 
    {
        XllpDmacStartTransfer( pHwContext->XllpDMA.dma_channels[0] );
    }

}

void PrvStopDMATransfer(P_HW_CONTEXT_T pHwContext)
{
    // stop channel 0
    XllpDmacStopTransfer( pHwContext->XllpDMA.dma_channels[0] );

    // stop channel 1 and 2  
    if ( pHwContext->XllpCAMERA.capture_output_format == XLLP_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR) 
    {
        XllpDmacStopTransfer( pHwContext->XllpDMA.dma_channels[1] );
        XllpDmacStopTransfer( pHwContext->XllpDMA.dma_channels[2] );
    }
}

XLLP_STATUS_T PrvStartCapture(P_HW_CONTEXT_T pHwContext, unsigned int block_id, unsigned int frames)
{
    XLLP_STATUS_T   status;
    
    // clear ci fifo
    XllpCIResetFIFO(pHwContext->XllpCAMERA.ci_reg_base);
    XllpCIClearInterruptStatus(pHwContext->XllpCAMERA.ci_reg_base, 0xFFFFFFFF);

    // start dma
    PrvStartDMATransfer(pHwContext, block_id);

    // start capture
    status = pHwContext->XllpCAMERA.camera_functions->start_capture(&pHwContext->XllpCAMERA, frames);    
    return status;
}


// Set the image format
XLLP_STATUS_T PrvSetDMARingBuffer(P_HW_CONTEXT_T pHwContext)
{
    unsigned frame_size;

    // ring buffer init
    switch(pHwContext->XllpCAMERA.capture_output_format) {
        case XLLP_CAMERA_IMAGE_FORMAT_RGB555:
        case XLLP_CAMERA_IMAGE_FORMAT_RGB565:
            frame_size = pHwContext->XllpCAMERA.capture_width * pHwContext->XllpCAMERA.capture_height * 2;
            pHwContext->XllpDMA.fifo0_transfer_size = frame_size;
            pHwContext->XllpDMA.fifo1_transfer_size = 0;
            pHwContext->XllpDMA.fifo2_transfer_size = 0;
            break;
        case XLLP_CAMERA_IMAGE_FORMAT_YCBCR422_PACKED:
            frame_size = pHwContext->XllpCAMERA.capture_width * pHwContext->XllpCAMERA.capture_height * 2;
            pHwContext->XllpDMA.fifo0_transfer_size = frame_size;
            pHwContext->XllpDMA.fifo1_transfer_size = 0;
            pHwContext->XllpDMA.fifo2_transfer_size = 0;
            break;
        case XLLP_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR:
            frame_size = pHwContext->XllpCAMERA.capture_width * pHwContext->XllpCAMERA.capture_height * 2;
            pHwContext->XllpDMA.fifo0_transfer_size = frame_size / 2;
            pHwContext->XllpDMA.fifo1_transfer_size = frame_size / 4;
            pHwContext->XllpDMA.fifo2_transfer_size = frame_size / 4;
            break;
        default:
            return XLLP_STATUS_WRONG_PARAMETER;
            break;
    }

    pHwContext->XllpDMA.block_size = frame_size;
    pHwContext->XllpDMA.block_number = pHwContext->XllpDMA.buf_size / frame_size;
    pHwContext->XllpDMA.block_header = pHwContext->XllpDMA.block_tail = 0;
    
    return XLLP_STATUS_SUCCESS;
}

// Set the image format
XLLP_STATUS_T PrvCameraSetCaptureFormat(P_HW_CONTEXT_T pHwContext)
{
    XLLP_STATUS_T status;

    status = XllpCameraSetCaptureFormat(&pHwContext->XllpCAMERA);

    if(status == XLLP_STATUS_SUCCESS)
    {
        status = PrvSetDMARingBuffer(pHwContext);
    }

    return status;
}


int  CameraSleep(void)
{
    RETAILMSG(1, (TEXT("CameraSleep\r\n")));

    return 0;
}

int  CameraResume(void)
{
    RETAILMSG(1, (TEXT("CameraResume\r\n")));

    XllpI2cInit((P_XLLP_I2C_T)(v_pI2C), (P_XLLP_GPIO_T) v_pGPIORegs, (P_XLLP_CLKMGR_T) v_pClkRegs, (XLLP_UINT32_T) 0);

    CameraInitSensor();

    return 0;
}

⌨️ 快捷键说明

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