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

📄 pxa27x_camera.c

📁 Windows CE 6.0 针对PXA270的开发板的BSP参考代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    XLLP_STATUS_T status;

    EnterCriticalSection(&CameraMutex);

    bDoStillCapture = FALSE;
    bDoVideoCapture = TRUE;

    XllpLock(I2C);

    // Configure the capture format.  Set the width, height, mode, and the physical addresses of the 
    // start of the descriptor chain.
    g_HwContext.XllpCAMERA.capture_width = g_HwContext.XllpCAMERA.Video_capture_width;
    g_HwContext.XllpCAMERA.capture_height = g_HwContext.XllpCAMERA.Video_capture_height;
    g_HwContext.XllpCAMERA.capture_mode = XLLP_CAMERA_MODE_RECORD;
    g_HwContext.XllpCAMERA.sensor_flip_mode = XLLP_CAMERA_VIDEO_FLIP_VERTICAL|
                                              XLLP_CAMERA_VIDEO_FLIP_HORIZONTAL;

    g_HwContext.XllpDMA.fifo0_descriptors_physical = VideoCaptureDescriptorPhysicalStartAddress_CH0;
    g_HwContext.XllpDMA.fifo1_descriptors_physical = VideoCaptureDescriptorPhysicalStartAddress_CH1;
    g_HwContext.XllpDMA.fifo2_descriptors_physical = VideoCaptureDescriptorPhysicalStartAddress_CH2;

    // set capture format
    status = PrvCameraSetCaptureFormat(&g_HwContext);
    if (status)
    {
        RETAILMSG(1,(TEXT("Camera init failure inside CameraSetCaptureFormat().\r\n")));
    }

    XllpCameraSetInterruptMask(&g_HwContext.XllpCAMERA, 
                               XLLP_CI_CICR0_FOM            | 
                               XLLP_CI_CICR0_EOFM           | 
                               XLLP_CI_CICR0_SOFM           | 
                               XLLP_CI_CICR0_CDM            |
                               XLLP_CI_CICR0_QDM            |
                               XLLP_CI_CICR0_PERRM          |
                               XLLP_CI_CICR0_EOLM           | 
                               XLLP_CI_CICR0_FEM);

    PrvStartCapture(&g_HwContext, 0, 0);
    
    XllpUnlock(I2C);

    LeaveCriticalSection(&CameraMutex);
}

void CameraStopVideoCapture()
{
    EnterCriticalSection(&CameraMutex);
    bDoVideoCapture = FALSE;

    XllpLock(I2C);

    // stop capture
    g_HwContext.XllpCAMERA.camera_functions->stop_capture(&g_HwContext.XllpCAMERA);    

    // stop dma
    PrvStopDMATransfer(&g_HwContext);

    XllpUnlock(I2C);

    LeaveCriticalSection(&CameraMutex);
}

void CameraCaptureStillImage()
{
    XLLP_STATUS_T status;
    EnterCriticalSection(&CameraMutex);

    XllpLock(I2C);

    // stop capture
    g_HwContext.XllpCAMERA.camera_functions->stop_capture(&g_HwContext.XllpCAMERA);    

    // stop dma
    PrvStopDMATransfer(&g_HwContext);



    discardframes = 0;

    // Configure the capture format.  Set the width, height, mode, and the physical addresses of the 
    // start of the descriptor chain.
    g_HwContext.XllpCAMERA.capture_width  = g_HwContext.XllpCAMERA.Still_capture_width;
    g_HwContext.XllpCAMERA.capture_height = g_HwContext.XllpCAMERA.Still_capture_height;
    g_HwContext.XllpCAMERA.capture_mode   = XLLP_CAMERA_MODE_STILL;
    g_HwContext.XllpCAMERA.sensor_flip_mode = XLLP_CAMERA_VIDEO_FLIP_HORIZONTAL |
                                              XLLP_CAMERA_STILL_FLIP_HORIZONTAL;

    g_HwContext.XllpDMA.fifo0_descriptors_physical = StillCaptureDescriptorPhysicalStartAddress_CH0;
    g_HwContext.XllpDMA.fifo1_descriptors_physical = StillCaptureDescriptorPhysicalStartAddress_CH1;
    g_HwContext.XllpDMA.fifo2_descriptors_physical = StillCaptureDescriptorPhysicalStartAddress_CH2;

    // Reset the buffer chain.  The application must now resubmit all capture buffers.
    bFirstVideoCaptureBufferSubmitted = FALSE;
    VirtAddr_Last_Pn_CH0 = 0x0;
    
    // set capture format
    status = PrvCameraSetCaptureFormat(&g_HwContext);
    if (status)
    {
            RETAILMSG(1,(TEXT("Camera init failure inside CameraSetCaptureFormat().\r\n")));
    //      return 1;
    }

    XllpCameraSetInterruptMask(&g_HwContext.XllpCAMERA, 
                               XLLP_CI_CICR0_FOM            | 
                               XLLP_CI_CICR0_EOFM           | 
                               XLLP_CI_CICR0_SOFM           | 
                               XLLP_CI_CICR0_CDM            |
                               XLLP_CI_CICR0_QDM            |
                               XLLP_CI_CICR0_PERRM          |
                               XLLP_CI_CICR0_EOLM           | 
                               XLLP_CI_CICR0_FEM);
    
    bDoStillCapture = TRUE;
    bDoVideoCapture = FALSE;

    // Enable the still image capture sequence.
    // Calling this routine once results in capture sequence that sometimes fails to interrupt
    // on the end of frame.
    // Calling this routine twice works around this problem - but it needs to be looked into
    // to root cause the failure.
 //   PrvStartCapture(&g_HwContext, 0, 1);
    PrvStartCapture(&g_HwContext, 0, 1);

    XllpUnlock(I2C);

    LeaveCriticalSection(&CameraMutex);
}

// Shut down this session of the camera driver and free all of the relevent resources allocated within.
int CameraShutdown(void)
{
   
    XllpLock(I2C);

    XllpCameraDeInit(&g_HwContext.XllpCAMERA);

    // Signal the ISR thread to shutdown
    SetEvent(hShutDown);

    XllpUnlock(I2C);

    return TRUE;
}

// A helper function that is called to configure the parameters that are later used 
// to configure the capture format.
int CameraChangeCaptureFormat(void)
{
    // TBD: call some real function
    return TRUE;
}


// Provides a physical address for a given user mode virtual address.
BOOL getPhyAddress (DWORD * pdwVirtual, DWORD * pdwPhysical)
{
    BOOL bReturnVal = TRUE;
    DWORD dwPageSize = UserKInfo[KINX_PAGESIZE];
    DWORD dwPageTableEntry;
    DWORD dwPageTablePart;
    DWORD dwOffsetInPage;

    /* query the page tables */
    if (LockPages (pdwVirtual, sizeof (DWORD), &dwPageTableEntry, LOCKFLAG_QUERY_ONLY) != TRUE)
    {
            bReturnVal = FALSE;
            goto cleanAndReturn;
    }

    /* shift left to make into a real address */
    dwPageTablePart = dwPageTableEntry << UserKInfo[KINX_PFN_SHIFT];

    /* figure out the offset in the page */
    dwOffsetInPage = ((DWORD) pdwVirtual) & (~UserKInfo[KINX_PFN_MASK]);

    /* combine the page table part and offset to create the address */
    *pdwPhysical = dwPageTablePart | dwOffsetInPage;

    cleanAndReturn:

    return (bReturnVal);
}
void CameraUnprepareBuffer(P_CAMERA_DMA_BUFFER_INFO pCamDmaBuf, int ucBufferType)
{
    DESCRIPTOR_INFO_T *pDescriptorInfo;

    pDescriptorInfo = NULL;
    bDoStillCapture = FALSE;
    bDoVideoCapture = FALSE;
    if (pCamDmaBuf)
    {
        if (pCamDmaBuf->BufferID >=0 && pCamDmaBuf->BufferID < MAX_CAMERA_DMA_BUFFERS)
        {
            pDescriptorInfo = MasterBufferList[pCamDmaBuf->BufferID];
        }
    }
    if (pDescriptorInfo)
    {
        free(pDescriptorInfo->pDescriptorBufferPhyAddress);
        free(pDescriptorInfo->pDescriptorBufferVirtAddress);
        free(pDescriptorInfo->pBufferPhyAddress);
        free(pDescriptorInfo);
        MasterBufferList[pCamDmaBuf->BufferID]= NULL;        
    }
    if (NumBuffers > 0)
    {
        NumBuffers--;
    }
        // We are going to unprepare all Video or still buffers
        // So we should initialize all related variables also

    if (ucBufferType == VIDEO_CAPTURE_BUFFER)
    {
        VirtAddr_Last_Pn_CH0 = 0x0;       
        VirtAddr_Last_Pn_CH1 = 0x0;
        VirtAddr_Last_Pn_CH2 = 0x0;

        // Address of the last real descriptor
        VirtAddr_Last_n_CH0 = 0x0;        
        VirtAddr_Last_n_CH1 = 0x0;        
        VirtAddr_Last_n_CH2 = 0x0;  

        // Physical address of the start of the video capture descriptor chain
        VideoCaptureDescriptorPhysicalStartAddress_CH0 = 0x0;
        VideoCaptureDescriptorPhysicalStartAddress_CH1 = 0x0;
        VideoCaptureDescriptorPhysicalStartAddress_CH2 = 0x0;

         // Set to true when the first video capture buffer has been submitted.
        bFirstVideoCaptureBufferSubmitted = FALSE;
    }
    else
    {
        // Physical address of the start of the still capture descriptor chain
        StillCaptureDescriptorPhysicalStartAddress_CH0 = 0x0;
        StillCaptureDescriptorPhysicalStartAddress_CH1 = 0x0;
        StillCaptureDescriptorPhysicalStartAddress_CH2 = 0x0;


        // Set to true when the first stll image buffer has been submitted
        bFirstStillBufferSubmitted = FALSE;


    }
    if (NumBuffers == 0)
    {
        if (VirtAddr_Phantom_Buffer_Base_Address)
        {
            free((void *)VirtAddr_Phantom_Buffer_Base_Address);
        }

        // Virtual address of the phantom buffer
        VirtAddr_Phantom_Buffer = 0x0;
        VirtAddr_Phantom_Buffer_Base_Address = 0x0;

        // Physical address of the phantom buffer
        PhysAddr_Phantom_Buffer = 0x0;
    }

    return;
}



//
// Submit a buffer to be filled by the camera DMA.
// A buffer is submitted by chaining the last buffer to this new buffer.
//
// Requires a valid FrameID, which is obtained from a successful call to PrepareBuffer().
//
void CameraSubmitBuffer(P_CAMERA_DMA_BUFFER_INFO pBufInfo, int BufferType)
{
    DESCRIPTOR_INFO_T *pDescriptorInfo;
    XLLP_DMAC_DESCRIPTOR_T *pXPn_CH0;
    XLLP_DMAC_DESCRIPTOR_T *pXPn_CH1;
    XLLP_DMAC_DESCRIPTOR_T *pXPn_CH2;

    XLLP_DMAC_DESCRIPTOR_T *pXn_CH0;
    XLLP_DMAC_DESCRIPTOR_T *pXn_CH1;
    XLLP_DMAC_DESCRIPTOR_T *pXn_CH2;

    XLLP_DMAC_DESCRIPTOR_T *pLast_Pn_CH0;
    XLLP_DMAC_DESCRIPTOR_T *pLast_Pn_CH1;
    XLLP_DMAC_DESCRIPTOR_T *pLast_Pn_CH2;

    XLLP_DMAC_DESCRIPTOR_T *pLast_n_CH0;
    XLLP_DMAC_DESCRIPTOR_T *pLast_n_CH1;
    XLLP_DMAC_DESCRIPTOR_T *pLast_n_CH2;

    BOOL isYUV_PLANAR;

    pDescriptorInfo = NULL;
    if (pBufInfo)
    {
        if (pBufInfo->BufferID >=0 && pBufInfo->BufferID < MAX_CAMERA_DMA_BUFFERS)
        {
                pDescriptorInfo = MasterBufferList[pBufInfo->BufferID];
        }
    }
    if (pDescriptorInfo)
    {
        isYUV_PLANAR = (3 == pDescriptorInfo->dwPlanesNumber ? TRUE : FALSE);

        // If this is the first buffer being submitted, then we want to store the physical address of the descriptor chain
        // so that when we start DMA's later on, we start with _this_ buffer.  All buffers submitted after this first buffer
        // are chained behind this one.  Therefore, this buffer is the logical choice to start with.    
        if (BufferType == VIDEO_CAPTURE_BUFFER)
        {
            if (bFirstVideoCaptureBufferSubmitted == FALSE)
            {
                VideoCaptureDescriptorPhysicalStartAddress_CH0 = pDescriptorInfo->pPhysAddr_X1_CH0;
                VideoCaptureDescriptorPhysicalStartAddress_CH1 = pDescriptorInfo->pPhysAddr_X1_CH1;
                VideoCaptureDescriptorPhysicalStartAddress_CH2 = pDescriptorInfo->pPhysAddr_X1_CH2;

⌨️ 快捷键说明

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