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

📄 pxa27x_camera.c

📁 Windows CE 6.0 针对PXA270的开发板的BSP参考代码
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
/**************************************************************************
** Copyright 2000-2004 Intel Corporation. All Rights Reserved.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.  
** Title to the Material remains with Intel Corporation or its suppliers and licensors. 
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.  
** No other 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 
** Some portion of the Materials may be copyrighted by Microsoft Corporation.

Module Name:  

    CAMERA.c

**************************************************************************/
#include <windows.h>
#include <ceddk.h>
#include <types.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <nkintr.h>
#include <giisr.h>
#include <bulverde.h>

#include "xllp_ci.h"
#include "xllp_i2c.h"
#include "xllp_serialization.h"

#include "pxa27x_camera.h"


#define ZONE_ERROR 1
#define ZONE_INIT  1
#define ZONE_VERBOSE 1


#define DMA_INTERRUPT_REGISTER  (BULVERDE_BASE_REG_PA_DMAC + (DWORD)&(((P_XLLP_DMAC_T)0)->DINT))


// Global variables

// Pointer to camera driver instance which we will send back with callback functions
DWORD dwCameraDriverContext;    

// Signals the application that the video or still image frame is available
PFNCAMHANDLEFRAME pfnCameraHandleVideoFrame = NULL;
PFNCAMHANDLEFRAME pfnCameraHandleStillFrame = NULL;

volatile XLLP_DMAC_T   * v_pDMARegs = NULL;
volatile XLLP_GPIO_T   * v_pGPIORegs = NULL;
volatile XLLP_CLKMGR_T * v_pClkRegs = NULL;
volatile unsigned int  * v_pOSTRegs = NULL;
volatile unsigned int  * v_pCIRegs = NULL;
volatile unsigned int  * v_pI2C = NULL;


// Local variables
//
static const LPCWSTR g_wszDmaIsrDll     = L"giisr.dll";
static const LPCWSTR g_wszDmaIsrHandler = L"ISRHandler";

// The camera hardware context
static HW_CONTEXT_T g_HwContext;

// The MasterBufferList contains pointers to a DESCRIPTOR_INFO_T structure for each buffer in the list.
// This is currently statically allocated.
static DESCRIPTOR_INFO_T *MasterBufferList[MAX_CAMERA_DMA_BUFFERS]; 

// Describes the current number of buffers that are contained in the Master Buffer List.
static DWORD NumBuffers = 0;

// Address of the last phantom descriptor
static XLLP_VUINT32_T VirtAddr_Last_Pn_CH0 = 0x0;       
static XLLP_VUINT32_T VirtAddr_Last_Pn_CH1 = 0x0;
static XLLP_VUINT32_T VirtAddr_Last_Pn_CH2 = 0x0;

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

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

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

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

// Physical address of the start of the still capture descriptor chain
static XLLP_VUINT32_T StillCaptureDescriptorPhysicalStartAddress_CH0 = 0x0;
static XLLP_VUINT32_T StillCaptureDescriptorPhysicalStartAddress_CH1 = 0x0;
static XLLP_VUINT32_T StillCaptureDescriptorPhysicalStartAddress_CH2 = 0x0;

// Set to true when the first video capture buffer has been submitted.
static BOOL bFirstVideoCaptureBufferSubmitted = FALSE;

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

// Used to provide synchronized access to certain camera functions
static CRITICAL_SECTION CameraMutex;

// Use to inform the interrupt service thread that a still capture event is occuring.
static unsigned int bDoStillCapture = FALSE;
static unsigned int bDoVideoCapture = FALSE;

// Used to discard a certain number of still image frames before signalling the application
// that the frame is available.  Some sensors output bad frames for the first few captured frames
// and they need to be "discarded."
static int discardframes = 0;

// Signals the application that a frame of motion video is available
static HANDLE hCameraFrameReady;

// Signals the application that the still image frame is available
static HANDLE hStillImageReady;

// Signals the application that the shutdown of the camera driver is complete.
static HANDLE hCameraShutdownComplete;

static HANDLE hShutDown;


static const XLLP_DMAC_DEVICE_T CAMERA_DMA_DEVICE[3] =
{
        XLLP_DMAC_QCI_RX1,
        XLLP_DMAC_QCI_RX2,
        XLLP_DMAC_QCI_RX3
};

static XLLP_STATUS_T PrvCameraDmacInit(HW_CONTEXT_T *pHwContext);
static XLLP_STATUS_T PrvCameraDmacDeinit(HW_CONTEXT_T *pHwContext);
static void PrvStartDMATransfer(P_HW_CONTEXT_T pHwContext, unsigned block_id);
static void PrvStopDMATransfer(P_HW_CONTEXT_T pHwContext);
static XLLP_STATUS_T PrvStartCapture(P_HW_CONTEXT_T pHwContext, unsigned int block_id, unsigned int frames);
static XLLP_STATUS_T PrvCameraSetCaptureFormat(P_HW_CONTEXT_T pHwContext);

static DWORD WINAPI CAMIntrThread(HW_CONTEXT_T *pHwContext);

VOID CameraInterfaceInterruptHandler(HW_CONTEXT_T *pHwContext)
{
    DWORD dwDCSR;
    DWORD dwDINT;
    int i;

    dwDINT = v_pDMARegs->DINT;
    DEBUGMSG(ZONE_VERBOSE, (TEXT( "CameraInterfaceInterruptHandler: DINT=0x%x\r\n" ), dwDINT));

    for(i=0; i<3; i++)
    if(dwDINT & (1<<pHwContext->XllpDMA.dma_channels[i]))
    {
        dwDCSR  = v_pDMARegs->DCSR[pHwContext->XllpDMA.dma_channels[i]];
        DEBUGMSG(ZONE_VERBOSE, (TEXT( "CameraInterfaceInterruptHandler: CH[%d] DCSR: 0x%x\r\n" ),pHwContext->XllpDMA.dma_channels[i], dwDCSR));

        // Provide waiting Object the current value of DCSR
        // SetEventData(pHwContext->hDMAEvent[i], dwDCSR);

        //did we get an error?
        if (dwDCSR & XLLP_DMAC_DCSR_BUS_ERR_INTR)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT( "DCSR_BUSERRINTR ERROR\r\n" )) );
            DEBUGCHK(0);  // an unplanned dma interrupt occured 
        }
    
        //did we get an start interrupt?
        if (dwDCSR & XLLP_DMAC_DCSR_START_INTR)  
        {
            DEBUGMSG(ZONE_VERBOSE, (TEXT( "DCSR_STARTINTR\n" )) );
            DEBUGCHK(0); // an unplanned dma interrupt occured 
        }
    
        //did we get an end interrupt?
        if (dwDCSR & XLLP_DMAC_DCSR_END_INTR)  //if the channel stopped at the end of a buffer xfer
        {
            DEBUGMSG(ZONE_ERROR, (TEXT( "DCSR_ENDINTR\r\n" )) );
        }

        //did we get an stop interrupt?
        if (dwDCSR & XLLP_DMAC_DCSR_STOP_INTR)  
        {
            DEBUGMSG(ZONE_VERBOSE, (TEXT( "DCSR_STOPINTR\r\n" )) );
            dwDCSR &= ~XLLP_DMAC_DCSR_STOP_IRQ_EN;
            DEBUGCHK(0); // an unplanned dma interrupt occured 
        }

        // Clear the status
        v_pDMARegs->DCSR[pHwContext->XllpDMA.dma_channels[i]] = dwDCSR;

        SetEvent(pHwContext->hDMAEvent[i]);
    }

    return;
}


DWORD DMAInterruptThread(HW_CONTEXT_T *pHwContext)
{
    DEBUGMSG(1, (TEXT("DMAInterruptThread\r\n")));

    while (TRUE)
    {
        WaitForSingleObject(pHwContext->hDmaIntrEvent,  INFINITE);
        // Grab the lock
        //Lock();

        CameraInterfaceInterruptHandler(pHwContext);

        //Unlock();
        
        InterruptDone(pHwContext->dwSysIntrDMA);

    }  // while(TRUE)

  return 0;
}

XLLP_STATUS_T   PrvCameraDmacInit(HW_CONTEXT_T *pHwContext)
{
    int i;
    _TCHAR EventName[20];
    DWORD dwDMAIrq = pHwContext->dwDmaIrq;

    for(i=0; i<3; i++)
    {
        // Get DMA channel event handler
        // Compose the name of the channel event for use with CreateEvent(...) below.
        wsprintf(EventName, TEXT("DMA_CHANNEL_%d"), pHwContext->XllpDMA.dma_channels[i]);

        pHwContext->hDMAEvent[i] = CreateEvent(NULL,FALSE,FALSE, EventName);
        if (pHwContext->hDMAEvent[i] == NULL)
        {
            DEBUGMSG(ZONE_ERROR,(TEXT("hDMAEvent (Named) is Zero...\r\n")));
            return (FALSE);  
        }
    }

    // Convert the hardwre DMA controller interrupt IRQ into a logical SYSINTR value
    if(!pHwContext->dwSysIntrDMA || pHwContext->dwSysIntrDMA == SYSINTR_UNDEFINED)
    {
        if(!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
                            &dwDMAIrq, sizeof(DWORD),
                            &pHwContext->dwSysIntrDMA, sizeof(DWORD), NULL))
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("Error obtaining DMA interrupt SYSINTR value!\n")));
            return (FALSE);
        }
    }

    // Install the DMA ISR handler
    if(pHwContext->hDMAIsrHandler == NULL)
    {
        GIISR_INFO Info;
        HANDLE hBusAccessHandle;
        PVOID PhysAddr;
        DWORD inIoSpace = 0;    // io space
        PHYSICAL_ADDRESS DmaRegisterAddress = {DMA_INTERRUPT_REGISTER, 0}; 

        pHwContext->hDMAIsrHandler = LoadIntChainHandler(g_wszDmaIsrDll, 
                                               g_wszDmaIsrHandler,
                                               (BYTE)dwDMAIrq);
        if(pHwContext->hDMAIsrHandler == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("LoadIntChainHandler (%s, %s, %d) failed!\r\n"),
                                            g_wszDmaIsrDll, 
                                            g_wszDmaIsrHandler,
                                            dwDMAIrq));
            return FALSE;
        }

        hBusAccessHandle = CreateBusAccessHandle((LPCTSTR)pHwContext->hDriverIndex);
        if(!BusTransBusAddrToStatic(hBusAccessHandle,
                                    Internal, 0,
                                    DmaRegisterAddress, sizeof(DWORD),
                                    &inIoSpace, &PhysAddr))
        {
            DEBUGMSG(ZONE_ERROR, (L"pxa27x_camera: Failed TransBusAddrToStatic\r\n"));
            return FALSE;
        }
            
        DEBUGMSG(ZONE_INIT, (L"Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d, PhysAddr = 0x%x\r\n", 
                g_wszDmaIsrDll, g_wszDmaIsrHandler, dwDMAIrq, PhysAddr));

        // Set up ISR handler
        Info.SysIntr    = pHwContext->dwSysIntrDMA;
        Info.CheckPort  = TRUE;
        Info.PortIsIO   = FALSE;
        Info.UseMaskReg = FALSE;
        Info.PortAddr   = (DWORD)PhysAddr;
        Info.PortSize   = sizeof(DWORD);
        Info.Mask       = (1 << pHwContext->XllpDMA.dma_channels[0]) |
                          (1 << pHwContext->XllpDMA.dma_channels[1]) |
                          (1 << pHwContext->XllpDMA.dma_channels[2]) ;

⌨️ 快捷键说明

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