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

📄 eintkey.c

📁 这个程序是基于Windows CE下的按键驱动程序源代码
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZHIYUAN electronics Co.,LTD.
**                                     
**                                 http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: 				EINTKey.c
** Last modified Date: 		2006-08-11
** Last Version:			V1.0		
** Description: 			This driver uses EINT4 button(KEY1) On MagicARM2410
**                          
**------------------------------------------------------------------------------------------------------
** Created By: 				MingYuan Zheng 郑明远
** Created date: 			2006-08-11
** Version: 				V1.0
** Descriptions:			The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/

#include <windows.h>
#include <types.h>
#include <excpt.h>
#include <tchar.h>
#include <cardserv.h>
#include <cardapi.h>
#include <tuple.h>
#include <devload.h>
#include <diskio.h>
#include <nkintr.h>
#include <windev.h>

#include <s3c2410x.h>
#include "EINTKey.h"

#define PRIVATE			static
#define PUBLIC

/* 读按键事件*/
PRIVATE HANDLE gReadKeyEvent[2];       

/* 按键按下中断事件 */
PRIVATE HANDLE gWaitEvent;

/* 是否退出中断服务线程 */
PRIVATE UINT32 g_bKillIST = FALSE;

/* 中断处理线程 */
PRIVATE HANDLE gEINTIntrThread;

/* 驱动打开计数器 */
PRIVATE UINT32 gOpenCount = 0;

/* EINT4 的物理中断号及逻辑中断号 */
PRIVATE UINT32 g_EINTIrq = IRQ_EINT4;
PRIVATE UINT32 g_EINTSysIntr = SYSINTR_UNDEFINED;

/* GPIO 寄存器对应的虚拟地址 */
PRIVATE volatile S3C2410X_IOPORT_REG * v_pIOPregs;

/*******************************************************************************************
函数名称: EINT_ConfigInterruptPin
描    述: 配置外部中断引脚并使能为 下降 沿触发
输入参数: 无	
输出参数: 无
返    回: 无
********************************************************************************************/
PRIVATE VOID EINT_ConfigInterruptPin(VOID)
{
	v_pIOPregs->GPFCON  &= ~(0x3 << 8);			/* Set EINT4(GPF4) as EINT4	*/
	v_pIOPregs->GPFCON  |=  (0x2 << 8);

    v_pIOPregs->EXTINT0 &= ~(0x7 << 16);		/* Configure EINT4 as falling edge tiggered Mode */
    v_pIOPregs->EXTINT0 |=  (0x2 << 16);
}

/*******************************************************************************************
函数名称: EINT_ConfigPinDefault
描    述: 配置外部中断引脚恢复为输入引脚
输入参数: 无	
输出参数: 无
返    回: 无
********************************************************************************************/
PRIVATE VOID EINT_ConfigPinDefault(VOID)
{
	v_pIOPregs->GPFCON  &= ~(0x3 << 8);			/* Set EINT4(GPF4) as GPIO(IN)  */
}


/*******************************************************************************************
函数名称: Key_IsPushed
描    述: 查询按键是否已按下
输入参数: 无	
输出参数: 无
返    回: FALSE: 按键未按下    TRUE: 按键已按下
*******************************************************************************************/
PRIVATE BOOL Key_IsPushed(VOID)
{
	return ((v_pIOPregs->GPFDAT & (1 << 4)) ? FALSE : TRUE);
}


/*******************************************************************************************
函数名称: EINT_InitializeAddresses
描    述: 取得相关寄存器的虚拟地址
输入参数: 无	
输出参数: 无
返    回: > 0 分配得到的虚拟地址;  FALSE: 分配失败  
*******************************************************************************************/
PRIVATE BOOL EINT_InitializeAddresses(VOID)
{
	BOOL	RetValue = TRUE;

	RETAILMSG(1, (TEXT(">>> EINT_initalization address..set..\r\n")));
		
	/* IO Register Allocation */
	v_pIOPregs = (volatile S3C2410X_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2410X_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (v_pIOPregs == NULL) 
	{
		ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
		RetValue = FALSE;
	}
	else 
	{
		if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2410X_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2410X_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) 
		{
			ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
			RetValue = FALSE;
		}
	}
	
	if (!RetValue) 
	{
		RETAILMSG (1, (TEXT("::: EINT_InitializeAddresses - Fail!!\r\n") ));
		if (v_pIOPregs) 
		{
			VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
		}

		v_pIOPregs = NULL;
	}
	else 
		RETAILMSG (1, (TEXT("::: EINT_InitializeAddresses - Success\r\n") ));

	return(RetValue);
}


/*******************************************************************************************
函数名称: EINTKey_IntrThread
描    述: 外部中断按键服务线程
输入参数: PVOID pArg:  	线程输入参数
输出参数: 无
返    回: 1 或 0
*******************************************************************************************/
DWORD EINTKey_IntrThread(PVOID pArg)
{
	DWORD ret;

	// 创建外部中断中断事件 
	gWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);		

	// 初始化外部按键中断: 注册中断事件, 允许外部中断
	if (!(InterruptInitialize(g_EINTSysIntr, gWaitEvent, 0, 0))) 
	{
		RETAILMSG(1, (TEXT("ERROR: EINTKey: InterruptInitialize failed.\r\n")));
		CloseHandle(gWaitEvent);
		return 0;
	}

	// 外部按键中断线程开始运行
	while (1) 
	{
		ret = WaitForSingleObject(gWaitEvent, INFINITE);
		if ((ret == WAIT_OBJECT_0) && (g_bKillIST == FALSE))
		{
			if (Key_IsPushed())			
			{
				Sleep(20);						/* 延时 20ms 用于滤去噪声	*/

				if (Key_IsPushed())		        /* 外部中断按键确实已按下 */
				{  
					SetEvent(gReadKeyEvent[0]);	/* 通知读函数, 外部中断按键按键按下 */		
					RETAILMSG(1, (TEXT("::: The Key1 Pushed. \r\n")));
				} 
			}
		}
		else
		{	
			CloseHandle(gWaitEvent);
			RETAILMSG(1, (TEXT("::: EINTKey_IntrThread Exit. \r\n")));
			return 0;	
		} //if (ret != WAIT_OBJECT_0) or Error occurs

		InterruptDone(g_EINTSysIntr);           /* 通知内核: 中断处理结束 */
	}      
  	
  	return 1;
}


/*******************************************************************************************
函数名称: KEY_Init
描    述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置 	
输出参数: 无
返    回: 驱动程序句柄
*******************************************************************************************/
PUBLIC DWORD KEY_Init(DWORD dwContext)
{
	DWORD IDThread;

	// 取得 GPIO 相关寄存器的虚拟地址空间
	if (EINT_InitializeAddresses() == FALSE)
	   return 0;		

	// 使能 EINT4 引脚为中断引脚, 并为下降沿触发
	EINT_ConfigInterruptPin();

    // 从 OAL 请求一个 SYSINTR 值
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_EINTIrq, sizeof(UINT32), &g_EINTSysIntr, sizeof(UINT32), NULL))
    {
        RETAILMSG(1, (TEXT("ERROR: EINTKey: Failed to request sysintr value for EINT interrupt.\r\n")));
        return(0);
    }
    RETAILMSG(1,(TEXT("INFO: EINTKey: Mapped Irq 0x%x to SysIntr 0x%x.\r\n"), g_EINTIrq, g_EINTSysIntr));

    // 创建一个外部中断处理线程 IST
	gEINTIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) EINTKey_IntrThread, 0, 0, &IDThread);
	if (gEINTIntrThread == NULL) 
	{
		RETAILMSG(1, (TEXT("::: KEY_Init: CreateThread() Fail.\r\n")));
		KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_EINTSysIntr, sizeof(UINT32), NULL, 0, NULL);
		return 0;
	}

	gReadKeyEvent[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
	gReadKeyEvent[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
  
    RETAILMSG(1, (TEXT("::: KEY_Init Sucessfully! \r\n")));
    
    // 返回不为0的数
	return (DWORD)gEINTIntrThread;
}


/*******************************************************************************************
函数名称: DllEntry
描    述: 驱动程序动态库入口
输入参数: 	
输出参数:
返    回: 
*******************************************************************************************/
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch ( dwReason ) 
	{
        case DLL_PROCESS_ATTACH:
            RETAILMSG(1, (TEXT("Key: DLL_PROCESS_ATTACH. \r\n")));
    		DisableThreadLibraryCalls((HMODULE) hInstDll);
            break;

        case DLL_PROCESS_DETACH:
            RETAILMSG(1, (TEXT("Key: DLL_PROCESS_DETACH. \r\n")));
            break;    
    }

    return (TRUE);
}


/*******************************************************************************************
函数名称: KEY_Close
描    述: 驱动程序关闭函数
输入参数: DWORD Handle:驱动程序句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功 
*******************************************************************************************/
BOOL KEY_Close(DWORD Handle)
{
	if (gOpenCount > 0)
		SetEvent(gReadKeyEvent[1]);						/* 通知调用读函数的线程, 驱动已经关闭 */

	gOpenCount = 0;

	return TRUE;
}   // KEY_Close



/*******************************************************************************************
函数名称: KEY_Deinit
描    述: 驱动程序卸载函数
输入参数: DWORD dwContext: 驱动程序句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功
*******************************************************************************************/
BOOL KEY_Deinit(DWORD dwContext)
{
	SetEvent(gWaitEvent);								/* 通知中断服务线程退出 */
    g_bKillIST = TRUE;						            
	Sleep(200);											/* 等待中断服务线程退出 */
   
	SetEvent(gReadKeyEvent[1]);							/* 通知调用读函数的线程, 驱动已经关闭 */

	// 释放中断资源
	InterruptDone(g_EINTSysIntr);
	InterruptDisable(g_EINTSysIntr);
	KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_EINTSysIntr, sizeof(UINT32), NULL, 0, NULL);
	
	// 恢复外部中断引脚为输入 GPIO
	EINT_ConfigPinDefault();     
	      
	// 释放申请的虚拟空间      
	if (v_pIOPregs)
		VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);   
    gOpenCount = 0;

  	CloseHandle(gReadKeyEvent[0]);						/* 关闭相关事件 */
	CloseHandle(gReadKeyEvent[1]);

	return TRUE;
}   // KEY_Deinit


/*******************************************************************************************
函数名称: KEY_Open
描    述: 打开驱动程序
输入参数: DWORD dwData     : 驱动程序引用事例句柄
          DWORD dwAccess   : 访问请求代码,是读和写的组合
          DWORD dwShareMode: 共享模式  
输出参数:
返    回: 驱动程序引用事例句柄
*******************************************************************************************/
DWORD KEY_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
    if (gOpenCount > 0)
        return 0;                // 本驱动只允许单一访问

    gOpenCount = 1;  
    return gOpenCount;
}   // KEY_Open


/*******************************************************************************************
函数名称: KEY_IOControl
描    述: 驱动程序 I/O 请求
输入参数: 
输出参数:
返    回: 本驱动不支持该请求,返回 FALSE
*******************************************************************************************/
BOOL
KEY_IOControl(
    DWORD Handle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    return FALSE;
}   // KEY_IOControl



/*******************************************************************************************
函数名称: KEY_Read
描    述: 读取按键状态
输入参数: DWORD Handle    : 驱动程序引用事例句柄
          LPVOID pBuffer  : 接收缓冲区
          DWORD dwNumBytes: 要读的字节数
输出参数: 无
返    回: 实际读到字节数
*******************************************************************************************/
DWORD KEY_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
	DWORD ret;
	uchar *pReadBuffer;

	if ((pBuffer == NULL) || (dwNumBytes <= 0))
		return 0;

	pReadBuffer = MapPtrToProcess(pBuffer, GetCallerProcess());
	*pReadBuffer = 0;

	/* 挂起当前线程,直到 KEY1 按键按下或驱动关闭 */
	ret = WaitForMultipleObjects(2, gReadKeyEvent, FALSE, INFINITE);	
	if (ret == WAIT_OBJECT_0)
	{
		ResetEvent(gReadKeyEvent[0]);
		*pReadBuffer = 1;										/* 按键按下 */
		return 1;
	}
	else if(ret == (WAIT_OBJECT_0 + 1))
	{
		ResetEvent(gReadKeyEvent[1]);
		*pReadBuffer = 0;										/* 驱动关闭 */
		return 1;		
	}
	
	return 0;
}   // KEY_Read


/*******************************************************************************************
函数名称: KEY_Write
描    述: 写函数,本驱动不支持
输入参数: 
输出参数:
返    回:
*******************************************************************************************/
DWORD KEY_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
	return 0;
}   // KEY_Write


/*******************************************************************************************
函数名称: KEY_Seek
描    述: 对设备的数据指针进行操作,本驱动不支持该函数
输入参数: 
输出参数:
返    回:
*******************************************************************************************/
DWORD KEY_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
	return 0;
}  // KEY_Seek


/*******************************************************************************************
函数名称: KEY_PowerUp
描    述: 电源上电驱动处理函数
输入参数: 
输出参数:
返    回: 无
*******************************************************************************************/
void KEY_PowerUp(void)
{
	return;
}  // KEY_PowerUp


/*******************************************************************************************
函数名称: KEY_PowerDown
描    述: 电源下电驱动处理函数
输入参数: 
输出参数:
返    回: 无
*******************************************************************************************/
void
KEY_PowerDown(void)
{
	return;
}  // KEY_PowerDown

⌨️ 快捷键说明

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