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

📄 usbcam.c

📁 Windows CE下USB驱动(OV511)
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZHIYUAN electronics Co.,LTD.
**                                     
**                                 http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: 				USBCAMERA.c
** Last modified Date: 		2007-01-9
** Last Version:			V1.0		
** Description: 			This driver Control the Usb Camera With Ov511 chip for PXA270
**                          
**------------------------------------------------------------------------------------------------------
** Created By: 				Wangyi Li 李望一
** Created date: 			2007-01-9
** Version: 				V1.0
** Descriptions:			The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/

#include "cam.h"
#include "String.h"

OV511STATUS ov;
DBGPARAM dpCurSettings;

static BYTE yQuanTable511[] = OV511_YQUANTABLE;
static BYTE uvQuanTable511[] = OV511_UVQUANTABLE;
static BYTE yQuanTable518[] = OV518_YQUANTABLE;
static BYTE uvQuanTable518[] = OV518_UVQUANTABLE;

static BYTE RawFrameData[115223];
static BYTE RealFrameData[115712];
static BYTE DataBuf[961 * 10];

HINSTANCE hInst;					 // DLL instance handle

USBCAMSTRUCT csCameras[] = 
{
	{ TEXT("OminiVision Ov511"),      VID_OMINIVISION, PID_OV511},
	{ TEXT("OminiVision WebEye 2000"),      VID_OMINIVISION, 0xA511},
	
};

static int autobright		= 1;
static int autogain		= 1;
static int autoexp		= 1;
static int debug;
static int snapshot;
static int cams			= 1;
static int compress;
static int testpat;
static int dumppix;
static int led 			= 1;
static int dump_bridge;
static int dump_sensor;
static int printph;
static int phy			= 0x1f;
static int phuv			= 0x05;
static int pvy			= 0x06;
static int pvuv			= 0x06;
static int qhy			= 0x14;
static int qhuv			= 0x03;
static int qvy			= 0x04;
static int qvuv			= 0x04;
static int lightfreq;
static int bandingfilter;
static int clockdiv		= -1;
static int packetsize		= -1;
static int framedrop		= -1;
static int fastset;
static int force_palette;
static int backlight;
static int remove_zeros;
static int mirror;
static int ov518_color;

//-----------------------------------------------------------------------
// IssueIsochTransfer - implements a synch isoch transfer to the device.
// This code was based on IssueVendorTransfer from USBClient.cpp 
// 
DWORD __inline IssueIsochTransfer (LPCUSB_FUNCS                 pUsbFuncs,   
                                   HANDLE                        hUsbDevice,                          
                                   LPTRANSFER_NOTIFY_ROUTINE    NotifyRoutine,       // Transfer completion routine.
                                   PVOID                        NotifyContext,       // Single argument passed to the completion routine
                                   DWORD                        Flags,               // USB_XXX flags describing the transfer
                                   DWORD                        dwStartingFrame,     // Starting frame to read
                                   DWORD                        dwNumFrames,         // Number of frames to read
                                   PDWORD                       pdwFrameLengths,     // Array that receives the length of each frame
                                   LPVOID                       pBuffer,             // Pointer to transfer buffer
                                   ULONG                        PhysAddr,            // Specifies the physical address, which may be NULL, of the data buffer
                                   LPDWORD                      pBytesTransferred,   // Number of bytes transferred by USB
                                   DWORD                        dwTimeout,           // Timeout in msec
                                   PUSB_ERROR                   pUsbRc)		         // Returns USB_ERROR or USB_TRANSFER
{
    USB_TRANSFER hTransfer;
    DWORD  dwErr = ERROR_SUCCESS;
    BOOL   bRc = TRUE;
    DWORD  z, dwWaitReturn;
    
    if (pUsbFuncs && hUsbDevice && pdwFrameLengths && pBytesTransferred && pUsbRc)  
    {
        *pUsbRc = USB_NO_ERROR;
        *pBytesTransferred = 0;
        
        if (NotifyContext && NotifyRoutine && dwTimeout) 
            ResetEvent(NotifyContext); // NotifyContext *must* be an EVENT
        
        hTransfer = pUsbFuncs->lpIssueIsochTransfer(hUsbDevice, 
                                                    NotifyRoutine,
                                                    NotifyContext, 
                                                    Flags, 
                                                    dwStartingFrame,
                                                    dwNumFrames, 
                                                    pdwFrameLengths,
                                                    pBuffer,
                                                    PhysAddr);
        if (hTransfer) 
        {
            //
            // Asynch call completed.
            // Get transfer status & number of bytes transferred
            //
            // 异步调用完成,则等待传输完成的回调事件,然后判断传输状态以及处理传输的数据
            if (NotifyContext && NotifyRoutine) 
            {
                DEBUGMSG(1,(TEXT("Asynch!\r\n")));
                if (!dwTimeout) 
                {
                    *pUsbRc = (USB_ERROR)hTransfer;
                    return dwErr;
                }
                
                //
                // sync the transfer completion / timer
                //
                dwWaitReturn = WaitForSingleObject( NotifyContext, dwTimeout );
                switch (dwWaitReturn) 
                {
                case WAIT_OBJECT_0:
                    //
                    // The completion event was signalled by the callback.
                    // Get transfer status & number of bytes transferred
                    //
                    bRc = pUsbFuncs->lpGetIsochResults (hTransfer, dwNumFrames, pdwFrameLengths, pUsbRc);
                    // sum total data transferred.
                    for (z = 0; z < dwNumFrames; z++)
                    {
                        *pBytesTransferred += pdwFrameLengths[z];
                        if (pUsbRc[z])
                        {
                            if ((pUsbRc[z] != USB_DATA_TOGGLE_MISMATCH_ERROR) && 
                                (pUsbRc[z] != USB_DATA_UNDERRUN_ERROR)) //Ignore underrun error
                            {
                                RETAILMSG(1,(TEXT("ERROR %d in frame %d\r\n"), pUsbRc[z], z)); 
                                dwErr = pUsbRc[z];
                                if (dwErr) break;
                            }
                        }
                    }
                    break;
                    
                case WAIT_TIMEOUT:
                    //
                    // The transfer reqest timed out.
                    // Get transfer status & number of bytes transferred
                    //
                    RETAILMSG(1,(TEXT("%s:WAIT_TIMEOUT on hT:0x%x\n"), (Flags & USB_IN_TRANSFER) ? TEXT("IN") : TEXT("OUT"), hTransfer ));
                    
                    GetTransferStatus(pUsbFuncs, hTransfer, pBytesTransferred, pUsbRc);
                    
                    //
                    // let caller know it timed out
                    //
                    dwErr = ERROR_TIMEOUT;
                    break;
                    
                default:
                    dwErr = ERROR_GEN_FAILURE;
                    RETAILMSG(1,(TEXT("*** Unhandled WaitReason:%d ***\n"), dwWaitReturn ));
                    // ASSERT(0);
                    break;
                }
            } 
            else 
            {
                //
                // Synch call completed.
                // Get transfer status & number of bytes transferred
                //
                // 同步调用完成,则不用WaitForSingleObject传输完成事件
                DEBUGMSG(1,(TEXT("Synch!\r\n")));
                bRc = pUsbFuncs->lpGetIsochResults (hTransfer, dwNumFrames, pdwFrameLengths, pUsbRc);
                // sum total data transferred.
                for (z = 0; z < dwNumFrames; z++)
                {
                    *pBytesTransferred += pdwFrameLengths[z];
                    if (pUsbRc[z])  
                    {
                        if (pUsbRc[z] != USB_DATA_UNDERRUN_ERROR) //Ignore underrun error
                            dwErr = pUsbRc[z];
                    }
                }
            }
            CloseTransferHandle(pUsbFuncs, hTransfer);
            
        } 
        else 
        {
            dwErr = ERROR_GEN_FAILURE;
            RETAILMSG(1,(TEXT("*** IssueIsochTransfer ERROR(3, 0x%x) ***\n"), dwErr ));
        }
        
    } else
        dwErr = ERROR_INVALID_PARAMETER;
    
    if (ERROR_SUCCESS != dwErr) 
    {
        SetLastError(dwErr);
        //DEBUGMSG(1,(TEXT("IssueIsochTransfer ERROR(5, BytesTransferred:%d, Win32Err:%d )\n"), 
        //			      pBytesTransferred?*pBytesTransferred:-1, dwErr)); 
    }
    return dwErr;
}

//写OV511寄存器
BOOL 
RegisterWrite(PDRVCONTEXT pDrv, 
              BYTE reg, 
              BYTE value)
{
    USB_DEVICE_REQUEST req;
    DWORD dwBytes;
    DWORD dw, dwErr;
    BOOL bRc = FALSE;
    BYTE buf = value;
	// Get our pdd specific context
    PDEVICECONTEXT pPDD = (PDEVICECONTEXT)pDrv->dwDeviceContext; 

    DEBUGMSG(1, (TEXT("RegisterWrite++\r\n")));    
    req.bmRequestType = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
    
    req.bRequest = 2;
    req.wValue   = 0;
    req.wIndex   = (USHORT)reg;
    req.wLength  = 1;
    

    
    dwBytes = 0;
    dwErr = USB_NO_ERROR;
    dw = IssueVendorTransfer (  pDrv->lpUsbFuncs, 
                                pDrv->hDevice, 
                                DefaultTransferComplete, 
                                pPDD->hVendorEvent,
                                USB_OUT_TRANSFER | USB_SHORT_TRANSFER_OK,
                                &req, 
                                &buf, 
                                (DWORD)NULL, 
                                &dwBytes, 
                                2000, 
                                &dwErr);
    if (dw)
    {
        DEBUGMSG(1, (TEXT("Error calling IssueVendorTransfer rc: %d  ExtErr: %d\r\n"), 
            dw, GetLastError()));
        bRc = FALSE;
    }
    else
    {
        // If no data transferred, stuff in an error
        if (!dw && (dwBytes != 1))
        {
            DEBUGMSG(1, (TEXT("No Data Transfered!\r\n")));
            dwErr = ERROR_BAD_LENGTH;
        }
        else
        {
            bRc = TRUE;
        }
    }
    DEBUGMSG(1, (TEXT("RegisterWrite-- rc %d,%d bytes transfered!\r\n"), dw,dwBytes));
    return bRc;
}

//读OV511寄存器
BOOL 
RegisterRead(  PDRVCONTEXT pDrv, 
                    BYTE reg, 
                    BYTE *value)
{
    USB_DEVICE_REQUEST req;
    DWORD dwBytes;
    DWORD dw, dwErr;
    BOOL bRc = FALSE;
    BYTE buf = 0;
    PDEVICECONTEXT pPDD = (PDEVICECONTEXT)pDrv->dwDeviceContext;     

    DEBUGMSG(1, (TEXT("RegisterRead++\r\n")));
    
    // Get our pdd specific context

    
    req.bmRequestType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
    
    req.bRequest = 3;
    req.wValue   = 0;
    req.wIndex   = (USHORT)reg;
    req.wLength  = 1;
   
    
    dwBytes = 0;
    dwErr = USB_NO_ERROR;
    dw = IssueVendorTransfer(   pDrv->lpUsbFuncs, 
                                pDrv->hDevice, 
                                DefaultTransferComplete,
                                pPDD->hVendorEvent,
                                USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK,
                                &req, 
                                &buf, 
                                (DWORD)NULL, 
                                &dwBytes, 
                                2000, 
                                &dwErr);
    if (dw)
    {
        RETAILMSG(1, (TEXT("Error calling IssueVendorTransfer rc: %d  ExtErr: %d\r\n"), 
            dw, GetLastError()));
    }
    else
    {     // If no data transferred, stuff in an error
        if (!dw && (dwBytes != 1))
        {
            RETAILMSG(1, (TEXT("No Data Transfered!\r\n")));
            dw = ERROR_BAD_LENGTH;
        }
        else
        {
            bRc = TRUE;
            *value = buf;
        }
    }
    
    DEBUGMSG(1, (TEXT("RegisterRead-- rc %d,%d bytes transfered!\r\n"), dw,dwBytes));
    return bRc;
}

/*
* Writes bits at positions specified by mask to an OV51x reg. Bits that are in
* the same position as 1's in "mask" are cleared and set to "value". Bits
* that are in the same position as 0's in "mask" are preserved, regardless
* of their respective state in "value".
*/
BOOL 
RegWriteMask(  PDRVCONTEXT pDrv,
               BYTE reg,
               BYTE value,
               BYTE mask)
{
    DWORD bRc;
    BYTE tmp;
    BYTE oldval, newval;
    
    bRc = RegisterRead(pDrv, reg, &tmp);
    if (bRc == FALSE)
        return bRc;
    
    oldval = (BYTE)tmp;
    oldval &= (~mask);		    //Clear the masked bits
    value &= mask;			    //Enforce mask on value
    newval = oldval | value;	//Set the desired bits 

    bRc = RegisterWrite(pDrv, reg, newval);

    return bRc;
}

BOOL
OV511IICWrite(PDRVCONTEXT pDrv,
              BYTE reg,
              BYTE value)
{
    int retries;
    BYTE tmp;
    BOOL bRc = FALSE;
    
    DEBUGMSG(1, (TEXT("OV511 Write IIC 0x%2X:0x%2X\r\n"), reg, value));
    
    /* Three byte write cycle */
    retries = OV511IICREADETRIES;
    while (1) {
        /* Select camera register */
        bRc = RegisterWrite(pDrv, R51x_I2C_SADDR_3, reg);
        if (bRc == FALSE)
            break;
        
        /* Write "value" to I2C data port of OV511 */
        bRc = RegisterWrite(pDrv, R51x_I2C_DATA, value);
        if (bRc == FALSE)
            break;
        
        /* Initiate 3-byte write cycle */
        bRc = RegisterWrite(pDrv, R511_I2C_CTL, 0x01);
        if (bRc == FALSE)
            break;
        
        /* Retry until idle */
        do
        {
            bRc = RegisterRead(pDrv, R511_I2C_CTL, &tmp);
        }
        while ((bRc == TRUE) && (tmp & 1) == 0); 
        if (bRc == FALSE)
            break;
        
        /* Ack? */
        if ((tmp & 2) == 0) {
            bRc = TRUE;
            break;
        }

        if (--retries < 0) {
            DEBUGMSG(1, (TEXT("i2c write retries exhausted\r\n")));

⌨️ 快捷键说明

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