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

📄 drv.cpp

📁 IIC WINCE5.0 流接口驱动程序及测试
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

    drv.c   I2C (logical) MDD

Abstract:

   Streams interface driver

Functions:

Notes:

--*/
#include "stdafx.h"
#include <nkintr.h>

#include <winreg.h>
#include <winioctl.h>
#include <ceddk.h>
#include <devload.h>

#include "drv.h"

#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("I2C"), 
	{
    TEXT("Error"), TEXT("Warn"),  TEXT("Init"),  TEXT("Open"),
    TEXT("Read"),  TEXT("Write"), TEXT("IOCTL"), TEXT("IST"),
    TEXT("Power"), TEXT("9"),     TEXT("10"),    TEXT("11"), 
    TEXT("12"),    TEXT("13"),    TEXT("14"),    TEXT("Trace"),
    },
    0xFFFF // ZONE_WRN|ZONE_ERR
};
#endif  // DEBUG


BOOL I2C_PowerUp(PVOID Context);
BOOL I2C_PowerDown(PVOID Context);

BOOL DllEntry(HINSTANCE   hinstDll,DWORD   dwReason,LPVOID  lpReserved)
{
    if ( dwReason == DLL_PROCESS_ATTACH ) 
	{
        DEBUGREGISTER(hinstDll);
        DEBUGMSG (ZONE_INIT, (TEXT("I2C: Process Attach\r\n")));
    }

    if ( dwReason == DLL_PROCESS_DETACH ) 
	{
        DEBUGMSG (ZONE_INIT, (TEXT("I2C: Process Detach\r\n")));
    }

    return(TRUE);
}


BOOL GetRegistryData(PI2C_CONTEXT pI2C, LPCTSTR regKeyPath)
{
    LONG    regError;
    HKEY    hKey;
    DWORD   dwDataSize;

    DEBUGMSG(ZONE_INIT, (TEXT("Try to open %s\r\n"), regKeyPath));

    // We've been handed the name of a key in the registry that was generated
    // on the fly by device.exe.  We're going to open that key and pull from it
    // a value that is the name of this drivers's real key.  That key
    // will have the DeviceArrayIndex that we're trying to find.  
    hKey = OpenDeviceKey(regKeyPath);
    if ( hKey == NULL ) 
	{
        DEBUGMSG(ZONE_INIT | ZONE_ERR,(TEXT("Failed to open device key\r\n")));
        return ( FALSE );        
    }

    dwDataSize = REG_MODE_VAL_LEN;
    regError = RegQueryValueEx(
                hKey, 
                REG_MODE_VAL_NAME, 
                NULL, 
                NULL,
                (LPBYTE)(&pI2C->Mode),
                &dwDataSize);

    if (regError)
        goto _done;

    dwDataSize = REG_SLAVEADDR_VAL_LEN;
    regError = RegQueryValueEx(
                hKey, 
                REG_SLAVEADDR_VAL_NAME,
                NULL, 
                NULL,
                (LPBYTE)(&pI2C->SlaveAddress),
                &dwDataSize);

    if (regError)
        goto _done;


_done:
    RegCloseKey (hKey);
    if ( regError != ERROR_SUCCESS ) 
	{
        DEBUGMSG(ZONE_ERR, (TEXT("Failed to get registry values, Error 0x%X\r\n"),regError));
        return ( FALSE );
    }
    DEBUGMSG (ZONE_INIT,(TEXT("I2C_Init - Mode: %s\r\n"),
        pI2C->Mode == POLLING ? L"POLLING" : L"INTERRUPT"));

    return ( TRUE ); 
}

static DWORD InternalMapRegisters(PI2C_CONTEXT pI2C)
{
//    PUCHAR  pVMem;
//    BOOL    bMapReturn;
    DWORD   err = ERROR_SUCCESS;
	PHYSICAL_ADDRESS IIC_PA_REG;
	PHYSICAL_ADDRESS IO_PA_REG;
  		
	IIC_PA_REG.HighPart=0;
	IIC_PA_REG.LowPart=S3C2410X_BASE_REG_PA_IICBUS;

	IO_PA_REG.HighPart=0;
	IO_PA_REG.LowPart=S3C2410X_BASE_REG_PA_IOPORT;


	pI2C->pI2CReg=(volatile S3C2410X_IICBUS_REG*)MmMapIoSpace(IIC_PA_REG,sizeof(S3C2410X_IICBUS_REG),false);
    pI2C->pIOPReg = (volatile S3C2410X_IOPORT_REG*)MmMapIoSpace(IO_PA_REG,sizeof(S3C2410X_IOPORT_REG),false);
	if((pI2C->pIOPReg==NULL) || (pI2C->pI2CReg==NULL))
	{
		err = GetLastError();
		DEBUGMSG(ZONE_ERR, (TEXT("Virtual Alloc ERROR: %d\r\n"), err));
	}

	/*
    // reserve enough space for our registers
    pVMem = (PUCHAR)VirtualAlloc(0, PAGE_SIZE*3, MEM_RESERVE, PAGE_NOACCESS);
    
    if (pVMem) 
	{
        // map in I2C registers
        bMapReturn = VirtualCopy( pVMem,
                                  (LPVOID)(S3C2410X_BASE_REG_PA_IICBUS>>8),
                                  PAGE_SIZE,
                                  PAGE_READWRITE | PAGE_NOCACHE |PAGE_PHYSICAL);
        if (!bMapReturn) 
		{
            err = GetLastError();
            DEBUGMSG(ZONE_ERR, (TEXT("Virtual Copy ERROR for IICBUS regs: %d\r\n"), err));
            return err;
        }
        pI2C->pI2CReg = (volatile S3C2410X_IICBUS_REG*)(pVMem);

        // map in GPIO registers
        pVMem += PAGE_SIZE;
        bMapReturn = VirtualCopy(pVMem,
                                 (LPVOID)(S3C2410X_BASE_REG_PA_IOPORT>>8),
                                 PAGE_SIZE,
                                 PAGE_READWRITE | PAGE_NOCACHE |PAGE_PHYSICAL);
        if (!bMapReturn) 
		{
            err = GetLastError();
            DEBUGMSG(ZONE_ERR, (TEXT("Virtual Copy ERROR for IOP regs: %d\r\n"), err));
            return err;
        }
        pI2C->pIOPReg = (volatile S3C2410X_IOPORT_REG*)(pVMem);
    }
	else
	{
        err = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("Virtual Alloc ERROR: %d\r\n"), err));
    }*/
	return err;
}

BOOL I2C_Deinit(PI2C_CONTEXT pI2C)
{
   DEBUGMSG(ZONE_INIT, (TEXT(">I2C_Deinit\n")));

    if (!pI2C)
        return FALSE;
        
    HW_Deinit(pI2C);
	if(pI2C->pI2CReg != NULL)
		MmUnmapIoSpace((PVOID)pI2C->pI2CReg,sizeof(S3C2410X_IICBUS_REG));
	if(pI2C->pIOPReg != NULL)
		MmUnmapIoSpace((PVOID)pI2C->pIOPReg,sizeof(S3C2410X_IOPORT_REG));
	LocalFree(pI2C);
	DEBUGMSG(ZONE_INIT, (TEXT("<I2C_Deinit\n")));
	return TRUE;
}


/*++

Called by Device Manager to initialize the streams interface in response to ActivateDevice.
We passed ActivateDevice a pointer to our device context, but must read it out of the registry as "ClientInfo".

Returns context used in XXX_Open, XXX_PowerDown, XXX_PowerUp, and XXX_Deinit

--*/
PI2C_CONTEXT I2C_Init(PVOID Context)
{
    LPTSTR ActivePath = (LPTSTR)Context; // HKLM\Drivers\Active\xx
    PI2C_CONTEXT pI2C;
    BOOL bRc = FALSE;

    DEBUGMSG(ZONE_INIT, (TEXT(">I2C_Init(%p)\n"), ActivePath));

    // Allocate for our main data structure and one of it's fields.
    pI2C = (PI2C_CONTEXT)LocalAlloc( LPTR,  sizeof(I2C_CONTEXT) );
    if ( !pI2C )
        return( NULL );

    pI2C->Sig = I2C_SIG;

    // read our config from registry
    if ( !GetRegistryData(pI2C, (LPCTSTR)Context) ) 
	{
        DEBUGMSG (ZONE_ERR, (TEXT("I2C_Init - Unable to read registry data.  Failing Init !!! \r\n")));
        goto ALLOCFAILED;
    }

    // map in register space
    if ( InternalMapRegisters(pI2C) != ERROR_SUCCESS)
        goto ALLOCFAILED;

    if ( HW_Init(pI2C) != ERROR_SUCCESS)
        goto ALLOCFAILED;

      
    DEBUGMSG(ZONE_INIT, (TEXT("<I2C_Init:0x%x\n"), pI2C ));

    return (pI2C);

ALLOCFAILED:
    I2C_Deinit(pI2C);
    return NULL;
}


PI2C_CONTEXT I2C_Open(PI2C_CONTEXT pI2C,       // context returned by I2C_Init.
   DWORD        AccessCode, // @parm access code
   DWORD        ShareMode   // @parm share mode
   )
{
    UNREFERENCED_PARAMETER(ShareMode);
    UNREFERENCED_PARAMETER(AccessCode);

    DEBUGMSG(ZONE_OPEN,(TEXT(">I2C_Open(0x%x, 0x%x, 0x%x)\n"),pI2C, AccessCode, ShareMode));

    pI2C->OpenCount++;

    HW_Open(pI2C);

    DEBUGMSG(ZONE_OPEN,(TEXT("<I2C_Open:%u\n"), pI2C->OpenCount ));

    return pI2C;
}


BOOL I2C_Close(PI2C_CONTEXT pI2C)
{
   DEBUGMSG(ZONE_OPEN,(TEXT("I2C_Close(0x%x)\n"),pI2C));
    if ( pI2C->OpenCount ) 
	{
        pI2C->OpenCount--;
        // BUGBUG: power off if no longer open
        HW_Close(pI2C);
    }

    return TRUE;
}


ULONG I2C_Write(PI2C_CONTEXT pI2C,PUCHAR pBuffer,ULONG  BufferLength)
{
    return 0;
}


ULONG I2C_Read(PI2C_CONTEXT pI2C,PUCHAR pBuffer,ULONG  BufferLength)
{
   return 0;
}


BOOL I2C_IOControl(PI2C_CONTEXT pI2C,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
    DWORD dwErr = ERROR_SUCCESS;
    BOOL  bRc = TRUE;
	LPBYTE pBuf=NULL;
	DWORD i;
	DWORD dwAddress,dwSlaveAddr,dwActiveAdress;
	I2C_IO_DESC *pI2C_Desc;

    DEBUGMSG(ZONE_IOCTL,(TEXT(">I2C_IOControl(0x%x, 0x%x, %d, 0x%x)\n"),
        dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut ));

    if ( !pI2C || !pI2C->OpenCount ) 
	{
        DEBUGMSG (ZONE_IOCTL|ZONE_ERR, (TEXT("I2C_IOControl: ERROR_INVALID_HANDLE\r\n")));
        SetLastError (ERROR_INVALID_HANDLE);
        return(FALSE);
    }

    if (pdwActualOut)
        *pdwActualOut = 0;

    //EnterCriticalSection(&pI2C->RegCS);

    switch (dwCode) 
	{
        // IOCTL_I2C_xxx
        case IOCTL_I2C_READ:
            if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->Data ) 
			{
                dwErr = ERROR_INVALID_PARAMETER;
                bRc = FALSE;
                break;
            }
			pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,(HANDLE) GetCurrentProcessId());
			if (pBufIn != NULL && pI2C_Desc == NULL) 
			{
				// Security violation
				DEBUGMSG(ZONE_ERR, (TEXT("I2CRead>Failed to map pointer to caller\r\n")));
                dwErr = ERROR_INVALID_PARAMETER;
                bRc = FALSE;
                break;
			}
			pBuf=(LPBYTE)MapPtrToProcess(pI2C_Desc->Data,(HANDLE) GetCurrentProcessId());
			if (pI2C_Desc->Data != NULL && pBuf == NULL) 
			{
				// Security violation
				DEBUGMSG(ZONE_ERR, (TEXT("I2CRead>Failed to map pointer to caller\r\n")));
                dwErr = ERROR_INVALID_PARAMETER;
                bRc = FALSE;
                break;
			}
            dwAddress = pI2C_Desc->WordAddr;
			for(i=0;i<pI2C_Desc->Count;i++)
			{
				dwActiveAdress = (dwAddress & 0xFF);
				dwSlaveAddr = (pI2C_Desc->SlaveAddr | (((dwAddress/255)&0x07)<<1));
				if(HW_Read(pI2C,dwSlaveAddr,(BYTE)dwActiveAdress, pBuf,1) == ERROR_SUCCESS)
				{
					pBuf++;
					dwAddress++;
					if (pdwActualOut)
						*pdwActualOut = i+1;
				}
				else
				{
					bRc = FALSE;
					break;
				}
			}
            UnMapPtr(pBuf);
            UnMapPtr(pI2C_Desc);
            break;

        case IOCTL_I2C_WRITE:
            if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->Data) 
			{
                dwErr = ERROR_INVALID_PARAMETER;
                bRc = FALSE;
                break;
            }
			pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,GetCurrentProcess());
			if (pBufIn != NULL && pI2C_Desc == NULL) 
			{
				// Security violation
				DEBUGMSG(ZONE_ERR, (TEXT("I2CRead>Failed to map pointer to caller\r\n")));
                dwErr = ERROR_INVALID_PARAMETER;
                bRc = FALSE;
                break;
			}
			pBuf=(LPBYTE)MapPtrToProcess(pI2C_Desc->Data,GetCurrentProcess());
			if (pI2C_Desc->Data != NULL && pBuf == NULL) 
			{
				// Security violation
				DEBUGMSG(ZONE_ERR, (TEXT("I2CWrite>Failed to map pointer to caller\r\n")));
                dwErr = ERROR_INVALID_PARAMETER;
                bRc = FALSE;
                break;
			}
			dwAddress = pI2C_Desc->WordAddr;
			for(i=0;i<pI2C_Desc->Count;i++)
			{
				dwActiveAdress = (dwAddress & 0xFF);
				dwSlaveAddr = (DWORD)(pI2C_Desc->SlaveAddr | (((dwAddress/255)&0x07)<<1));
				if (HW_Write(pI2C,dwSlaveAddr,(BYTE)dwActiveAdress,pBuf,1) ==  ERROR_SUCCESS)
				{
					pBuf++;
					dwAddress++;
					if (pdwActualOut)
						*pdwActualOut = i+1;
				}
				else
				{
					bRc = FALSE;
					break;
				}
			}
            
            UnMapPtr(pBuf);
			UnMapPtr(pI2C_Desc);
            break;

/*        case IOCTL_I2C_GET_FASTCALL:
            if ( (dwLenOut < sizeof(I2C_FASTCALL)) || !pBufOut ) 
			{
                bRc = FALSE;
                dwErr = ERROR_INVALID_PARAMETER;
                break;
            }

            // Check caller process & fail if they are not in device.exe!
            if (GetCallerProcess() != pI2C->hProc ) {
                DEBUGMSG (ZONE_ERR, (TEXT("ERROR_ACCESS_DENIED: Caller(0x%X) != Current(0x%X)\r\n"), 
                    GetCallerProcess(), pI2C->hProc ));
                bRc = FALSE;
                dwErr = ERROR_ACCESS_DENIED;
                break;
            }
            
            ((PI2C_FASTCALL)pBufOut)->Context  = pI2C;
            ((PI2C_FASTCALL)pBufOut)->I2CRead  = HW_Read;
            ((PI2C_FASTCALL)pBufOut)->I2CWrite = HW_Write;

            if (pdwActualOut)
                *pdwActualOut = sizeof(I2C_FASTCALL);

            break;

        //
        // Power Management
        //
        case IOCTL_POWER_CAPABILITIES:
            if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(POWER_CAPABILITIES)) ) 
			{
                bRc = FALSE;
                dwErr = ERROR_INVALID_PARAMETER;
                break;
            }
            
            bRc = HW_PowerCapabilities(pI2C, (PPOWER_CAPABILITIES)pBufOut);
            if ( bRc ) {
                *pdwActualOut = sizeof(POWER_CAPABILITIES);
            }
            break;

        case IOCTL_POWER_SET: 
            if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) )
			{
                bRc = FALSE;
                dwErr = ERROR_INVALID_PARAMETER;
                break;
            }

            bRc = HW_PowerSet(pI2C, (PCEDEVICE_POWER_STATE)pBufOut);
            if ( bRc ) 
			{
                *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
            }
            break;

        case IOCTL_POWER_GET: 
            if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) )
			{
                bRc = FALSE;
                dwErr = ERROR_INVALID_PARAMETER;
                break;
            }

            bRc = HW_PowerGet(pI2C, (PCEDEVICE_POWER_STATE)pBufOut);
            if ( bRc ) 
			{
                *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
            }
            break;*/


        default:
            bRc  = FALSE;
            dwErr = ERROR_INVALID_FUNCTION;
            DEBUGMSG (ZONE_ERR, (TEXT("I2C_IOControl Unknown Ioctl: 0x%X\r\n"), dwCode));
            break;            
    }

    //LeaveCriticalSection(&pI2C->RegCS);

    if ( !bRc )
	{
        DEBUGMSG (ZONE_ERR, (TEXT("I2C_IOControl ERROR: %u\r\n"), dwErr));
        SetLastError(dwErr);
    }

    DEBUGMSG(ZONE_IOCTL,(TEXT("<I2C_IOControl:%d\n"), bRc));

    return bRc;
}


ULONG I2C_Seek(PVOID Context,LONG  Position,DWORD Type)
{
    return (ULONG)-1;
}


BOOL I2C_PowerUp(PVOID Context)
{
    return HW_PowerUp((PI2C_CONTEXT)Context);
}


BOOL I2C_PowerDown(PVOID Context)
{
    return HW_PowerDown((PI2C_CONTEXT)Context);
}



⌨️ 快捷键说明

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