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

📄 keypad.cpp

📁 串口驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			// Disable key release interrupts and re-enable key depress interrupts.
			gpKpp->KPSR |= (bmKPSR_KDIE | bmKPSR_KPKR | bmKPSR_KPKD | bmKPSR_KDSC);
		}
		else
		{
			DEBUGMSG(KEY_ERROR_MSG|KEY_DEBUG_MSG, (TEXT("\r\nKEY_IntrThread: undesired interrupt! KPSR 0x%04x.\r\n"), tempKPSR));
			gpKpp->KPSR |= (tempKPSR | bmKPSR_KPKD | bmKPSR_KPKR | bmKPSR_KDSC | bmKPSR_KRSS);
		}
		DEBUGMSG(KEY_DEBUG_MSG, (TEXT("InterruptDone!\r\n")));
		LeaveCriticalSection(&ghKppLock);
		InterruptDone(SYSINTR_KPP);
	}
}//中断处理函数处理完毕

/***********************************************************************
 *
 *  FUNCTION:		Key_Init           初始化,启动中断服务.该部分是我们参考的重点
 *
 *  DESCRIPTION:	This function is to initialize the KPP 
 *               and start a interrupt thread for keypad
 *
 *  NOTE:
 *
 *  PARAMETERS:	
 *
 *  RETURNS:		
 *
 **********************************************************************/
DWORD KEY_Init(DWORD dwContext)
{
	DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Init: dwContext = 0x%x\r\n"), dwContext));

	//------------------------------------------------
	//map KPP memory space,为了让中断服务线程IST在用户模式下访问设备,必须要访问一个物理存储区
	//使用VirtualAlloc函数保留一块虚拟存储区,返回的是该区的指针
	//申请成功后,使用VirtualCopy函数将这个块的存储区和物理内存的一块映射起来.
	//------------------------------------------------	
	if(gpKpp == NULL)
	{
		gpKpp = (pKppReg_t) VirtualAlloc( 0,
					          sizeof(kppReg_t),
						  MEM_RESERVE, 
						  PAGE_NOACCESS); //申请虚拟存储区,从0开始,保留并且不许访问

		if(gpKpp == NULL) 
		{
			ERRORMSG(KEY_DEBUG_MSG|KEY_ERROR_MSG, (TEXT("KEY_Init: KPP memory space VirtualAlloc failed!\r\n")));
			return 0;
		}
		else
		{
			if (!VirtualCopy (gpKpp,
					  (LPVOID)GET_V_ADDR_REG(KPP_BASE, 0),
					  sizeof(kppReg_t),
					  (PAGE_READWRITE | PAGE_NOCACHE)) )
			{
				ERRORMSG(KEY_DEBUG_MSG|KEY_ERROR_MSG, (TEXT("KEY_Init: KPP memory sapce VirtualCopy failed!\r\n")));
				return 0;
			}		//建立映射关系,GET_V_ADDR_REG得到的是键值的物理存储区
		}		

		DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Init: KPP memory space bind successful! \r\n")));
	}


	//------------------------------------------------
	//Initialize KPP hardware according to IC Spec (V1.4)
	//------------------------------------------------	
	//enable KPP
	gpKppPmuClass= new PmuClass;
	gpKppPmuClass->EnableKpp(TRUE); //新建立一个PMU的派生类并使能KPP
	//以下是键盘扫描
	// Enable no. of rows in keypad (KRE = 1)
	// Configure columns as open-drain (KCO = 1)
	SET_2BITS(gpKpp->KPCR, KPCR_KRE, KPP_ROW_MASK, KPCR_KCO, KPP_COLUMN_MASK);

	// Write 0's to all columns
	SET_BITS(gpKpp->KPDR, KPDR_KCD, 0);

	// Configure rows as input, columns as output
	SET_2BITS(gpKpp->KDDR, KDDR_KCDD, KPP_COLUMN_MASK, KDDR_KRDD, 0);

	// Clear KPKD and KPSR_KPKR status flag (w1c)
	// Clear synchronizer chain - KDSC (w1c)
	// Enable keypad interrupt - Set KDIE, clear KRIE (avoid false release events)
	gpKpp->KPSR = \
			SET_VALUE(KPSR_KPP_EN, 1) |
			SET_VALUE(KPSR_KPKD, 1) |
			SET_VALUE(KPSR_KPKR, 1) |
			SET_VALUE(KPSR_KDSC, 1) |
			SET_VALUE(KPSR_KDIE, 1) |
			SET_VALUE(KPSR_KRIE, 0) ;

	
	//------------------------------------------------
	//Setup and start interrupt
	//------------------------------------------------	
	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); //设置当前线程优先级

	DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Init: CreateEvent\r\n")));
	ghIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //创建一个无名事件,并返回该事件的句柄
	if (ghIntrEvent == NULL) 
	{
		ERRORMSG(KEY_ERROR_MSG|KEY_DEBUG_MSG, (TEXT("KEY_Init: CreateEvent failed\r\n")));
		return 0;
	}

	if(!InterruptInitialize(SYSINTR_KPP, ghIntrEvent, NULL, NULL)) //初始化硬件中断,分别是中断号\中断触发事件\数据区指针\数据区大小
	{
		CloseHandle(ghIntrEvent);//如果中断初始化失败,则关闭事件
		ghIntrEvent = NULL;
		ERRORMSG(KEY_ERROR_MSG|KEY_DEBUG_MSG, (TEXT("KEY_Init: Interrupt initialization failed! \r\n")));
		return 0;
	}

	DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Init: CreateThread\r\n")));//建立线程
	ghIntrThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)KEY_IntrThread, NULL, 0, NULL); //调用上面设计的中断服务线程,返回一个新线程的句柄line87
	if (ghIntrThread == NULL) 
	{
		ERRORMSG(KEY_ERROR_MSG|KEY_DEBUG_MSG, (TEXT("KEY_Init: Failed to create KEY Interrupt Service Thread\r\n")));
		return 0;
	}
   
	DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Init: Exit Initialization\r\n")));
   
	return 0x5678;
}//初始化完成,全部正常返回0x5678



/***********************************************************************
 *
 *  FUNCTION:		Key_Deinit
 *
 *  DESCRIPTION:	This function is to clearup when dll is unloaded.
 *
 *  NOTE:
 *
 *  PARAMETERS:	
 *
 *  RETURNS:		
 *
 **********************************************************************/
BOOL KEY_Deinit(DWORD dwContext)
{
	DEBUGMSG(KEY_DEBUG_MSG, (TEXT("+KEY_Deinit: dwContext = 0x%x\r\n"), dwContext));

	InterruptDisable(SYSINTR_KPP); //卸载后不再响应中断
	
	if (ghIntrThread != NULL) 
	{
		CloseHandle(ghIntrThread);//关闭中断线程
		ghIntrThread = NULL;
	}
   
	if (ghIntrEvent != NULL) 
	{
		CloseHandle(ghIntrEvent);//事件也关闭
		ghIntrEvent = NULL;
	}

	gpKpp->KPSR = 0;
	if(gpKpp != NULL)
	{
		VirtualFree (gpKpp, 0, MEM_RELEASE);//释放缓存区
		gpKpp = NULL;
	}

	gpKppPmuClass->EnableKpp(FALSE);//屏蔽KPP
	delete gpKppPmuClass;//删除并释放资源
	gpKppPmuClass = NULL;		

	// the device manager does not check the return code
	DEBUGMSG(KEY_DEBUG_MSG, (TEXT("-KEY_Deinit\r\n"), dwContext));
   
	return TRUE;	
}




//----------------------------------------------------------------------------
//The following codes do nothing at all
//----------------------------------------------------------------------------

/*---------------------------------------------------------------------------*/
DWORD KEY_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("+KEY_Open: dwData = 0x%x, dwAccess = 0x%x, dwShareMode = 0x%x\r\n"), dwData, dwAccess, dwShareMode));
   
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("-KEY_Open\r\n")));
   
   return dwData;
}

/*---------------------------------------------------------------------------*/
BOOL KEY_Close(DWORD Handle)
{
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("+KEY_Close: Handle = 0x%x\r\n"), Handle));
   
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("-KEY_Close: Handle = 0x%x\r\n"), Handle));
   
   return TRUE;
}


/*---------------------------------------------------------------------------*/
// do not make any Win32 calls!  (including retail messages)
void KEY_PowerDown(void)
{
	// trap suspend events not initiated by keypad.
	KppSuspend = TRUE;
	keyDown[KPP_POWER_COL] |= (1 << KPP_POWER_ROW);

	// Configure keypad to generate interrupts for wake keys only
	SET_2BITS(gpKpp->KPCR, KPCR_KCO, KPP_WAKEUP_COL_MASK, KPCR_KRE, KPP_WAKEUP_ROW_MASK);
	SET_BITS(gpKpp->KPDR, KPDR_KCD, ~KPP_COLUMN_MASK);
	SET_2BITS(gpKpp->KDDR, KDDR_KCDD, KPP_WAKEUP_COL_MASK, KDDR_KRDD, ~KPP_WAKEUP_ROW_MASK);
	gpKpp->KPSR |= (bmKPSR_KDIE | bmKPSR_KPKD | bmKPSR_KPKR | bmKPSR_KDSC | bmKPSR_KRSS);
}


/*---------------------------------------------------------------------------*/
// do not make any Win32 calls!  (including retail messages)
void KEY_PowerUp(void)
{
	// prepare to resume by either re-opening the device or resetting it to closed
	// Restore keypad configuration and 
	// enable key up interrupts for handling of resume keys.
	SET_2BITS(gpKpp->KPCR, KPCR_KCO, KPP_COLUMN_MASK, KPCR_KRE, KPP_ROW_MASK);
	SET_BITS(gpKpp->KPDR, KPDR_KCD, ~KPP_COLUMN_MASK);
	SET_2BITS(gpKpp->KDDR, KDDR_KCDD, KPP_COLUMN_MASK, KDDR_KRDD, ~KPP_ROW_MASK);
	gpKpp->KPSR = (bmKPSR_KPP_EN | bmKPSR_KRIE | bmKPSR_KPKR | bmKPSR_KRSS);

}

/*---------------------------------------------------------------------------*/
DWORD KEY_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Read: Handle = 0x%x, pBuffer = 0x%x, dwNumBytes = 0x%x\r\n"), Handle, pBuffer, dwNumBytes));
   return 0;
}
//this debug message could be used by us,我们可以参考这样的调试信息
/*---------------------------------------------------------------------------*/
DWORD KEY_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Write: Handle = 0x%x, pBuffer = 0x%x, dwNumBytes = 0x%x\r\n"), Handle, pBuffer, dwNumBytes));

   return 0;
}

/*---------------------------------------------------------------------------*/
DWORD KEY_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_Seek: Handle = 0x%x, lDistance = 0x%x, dwMoveMethod = 0x%x\r\n"), Handle, lDistance, dwMoveMethod));

   return (DWORD) -1;
}

/*---------------------------------------------------------------------------*/
BOOL KEY_IOControl(DWORD Handle, DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize,
                   PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
   DEBUGMSG(KEY_DEBUG_MSG, (TEXT("+KEY_IOControl: Handle = 0x%x, dwIoControlCode = 0x%x\r\n"), Handle, dwIoControlCode));

   return TRUE;
}

/*---------------------------------------------------------------------------*/
BOOL WINAPI KEY_DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
   switch (dwReason) {
      case DLL_PROCESS_ATTACH:
         DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_DllEntry: DLL_PROCESS_ATTACH\r\n")));
         break;
         
      case DLL_PROCESS_DETACH:
         DEBUGMSG(KEY_DEBUG_MSG, (TEXT("KEY_DllEntry: DLL_PROCESS_DETACH\r\n")));
         break;
   }
   
   // return TRUE for success
   return TRUE;
}

/*********************************************************************
 PRIVATE FUNCTIONS
*********************************************************************/
/*********************************************************************
 *
 *  FUNCTION:		kppHandleWakeKeys
 *
 *  DESCRIPTION:	This function what wake keys(non power key)
 *					are depressed and handles accordingly.
 *
 *  PARAMETERS:		current keypad row/col matrix data
 *
 *  RETURNS:		None
 *
 ********************************************************************/
static void kppHandleWakeKeys(UINT8 *keys)
{
	UINT8 iCol;
	UINT8 iRow;
	UINT8 iRowMask;
	UINT8 index;

	for(iCol = 0; iCol < KPP_COLUMN_INUSE; iCol++)
	{
		for(iRow = 0, iRowMask = 1; iRow < KPP_ROW_INUSE; iRow++, iRowMask <<= 1)
		{
			if(iRowMask & keys[iCol])
			{
				index = iCol * KPP_ROW_INUSE + iRow;
				if(index != KPP_POWER_BUTTON_INDEX)
				{
					if(ExtraKeyCodeSequenceTable[index] != 0)
						keybd_event(ExtraKeyCodeSequenceTable[index], index, 0, 0);
					keybd_event(KeyCodeSequenceTable[index], index, 0, 0);
				}
			}
		}
	} 
}

/*********************************************************************
 END OF FILE
*********************************************************************/

⌨️ 快捷键说明

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