/*******************************************************************************************
函数名称: EINTKey_IntrThread
描 述: 外部中断按键服务线程
输入参数: PVOID pArg: 线程输入参数
输出参数: 无
返 回: 1 或 0
*******************************************************************************************/
DWORD EINTKey_IntrThread(PVOID pArg)
{
DWORD ret;
DWORD pressRowNo;
DWORD pressColNo;
// 创建外部中断中断事件
gWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// 初始化外部按键中断: 注册中断事件, 允许外部中断
if (!(InterruptInitialize(SYSINTR_Key, 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);
if(Key_IsPushed())
{
EINT_ConfigPinDefault( );
KEY_Scan();
SetEvent(gReadKeyEvent[0]);
RETAILMSG(1,(TEXT(":::The Key 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(SYSINTR_Key); /* 通知内核: 中断处理结束 */
}
return 1;
}
/*******************************************************************************************
函数名称: KEY_Init
描 述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置
输出参数: 无
返 回: 驱动程序句柄
*******************************************************************************************/
PUBLIC DWORD KEY_Init(DWORD dwContext)
{
DWORD IDThread;
// 取得 GPIO 相关寄存器的虚拟地址空间
if (EINT_InitializeAddresses() == FALSE)
return 0;
EINT_ConfigInterruptPin();
// 从 OAL 请求一个 SYSINTR 值
/*#if 0
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));
#endif*/
// 创建一个外部中断处理线程 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]);
/* 通知调用读函数的线程, 驱动已经关闭 */
RETAILMSG(1, (TEXT("Key: close... \r\n")));
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(SYSINTR_Key);
InterruptDisable(SYSINTR_Key);
// 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)
{
RETAILMSG(1, (TEXT("Key: OPEN... \r\n")));
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;
DWORD waitMillSec;
DWORD *pReadBuffer;
if ((pBuffer == NULL) || (dwNumBytes