nleddrv.cpp

来自「扬创yc2440-t2-dm9000 ce 5.0 bsp」· C++ 代码 · 共 496 行

CPP
496
字号
#include <windows.h>
#include <nled.h>
#include <led_drvr.h>
#include "ceddk.h"
#include "s2440.h"

//------------------------------------------------------------------------------
// External	Variables

//------------------------------------------------------------------------------
// Defines

//------------------------------------------------------------------------------
// Types
typedef	enum {
	NLED1=0,
	NLED2,
	NLED3,	
	NLED4,
	NLED_MAX
} NLED;

typedef	enum {
	NLED_OFF=0,
	NLED_ON,
	NLED_BLINK,
	NLED_INVALID
} NLED_MODE;

typedef	struct {
	IOPreg *pEioReg;
	BOOL bLedState[NLED_MAX];	 
	BOOL bStopLedThread[NLED_MAX];	 
	HANDLE hLedThread[NLED_MAX];	
	HANDLE hUpdateLedThreadEvent[NLED_MAX];
	NLED_SETTINGS_INFO curSetting[NLED_MAX];
} NLED_DRVR_INFO, *PNLED_DRVR_INFO;

//------------------------------------------------------------------------------
// Global Variables

//------------------------------------------------------------------------------
// Local Variables
static NLED_DRVR_INFO *gp_nleddrvrInfo;

//------------------------------------------------------------------------------
//
// Function: SetLedHw
//
// This	routine	sets the LED hw	as per desired settings.
//
// Parameters:	
//		pCurSetting
//			[in] Pointer of NLED_SETTINGS_INFO.
//
// Returns:
//		TRUE indicates success. FALSE indicates failure.
//
//------------------------------------------------------------------------------
static BOOL	SetLedHw(NLED_SETTINGS_INFO	*pCurSetting)
{
	BOOL fOk = TRUE;

	if (pCurSetting->LedNum < NLED_MAX) {
		if (pCurSetting->OffOnBlink >= NLED_INVALID) {
			DEBUGMSG(ZONE_ERROR, (TEXT("SetLedHw: Unsupported Mode Setting\r\n")));
			SetLastError(ERROR_INVALID_PARAMETER);
			fOk	= FALSE;
			goto SetLedHw_Err;
		}

		if (pCurSetting->OffOnBlink	== NLED_BLINK 
			&& (pCurSetting->OnTime	< 1000 /*|| pCurSetting->OffTime < 1000*/)) {
			DEBUGMSG(ZONE_ERROR, (TEXT("SetLedHw: Unsupported On/Off Time\r\n")));
			SetLastError(ERROR_INVALID_PARAMETER);
			fOk	= FALSE;
			goto SetLedHw_Err;
		}
			
		if (!SetEvent(gp_nleddrvrInfo->hUpdateLedThreadEvent[pCurSetting->LedNum])) {
			DEBUGMSG(ZONE_ERROR, (TEXT("SetLedHw: Unable to	update thread\r\n")));
			SetLastError(ERROR_INVALID_HANDLE);
			fOk	= FALSE;
		}
	} else {
		DEBUGMSG(ZONE_ERROR, (TEXT("SetLedHw: Unsupported LED Number\r\n")));
		SetLastError(ERROR_INVALID_PARAMETER);
		fOk = FALSE;
	}

SetLedHw_Err:
	return fOk;
}  

//------------------------------------------------------------------------------
//
// Function: LedThread
//
// Notification	LED	blink thread.
//
// Parameters:
//		lpParameter
//			[in/out] Parameters for the thread.
//
// Returns:
//		0	
//
//------------------------------------------------------------------------------
static DWORD WINAPI	LedThread(LPVOID lpParameter)
{
	BOOL bLedOn;
	NLED_SETTINGS_INFO *p;
	DWORD OnTime, OffTime, WaitTime, Ret;

	p =	(NLED_SETTINGS_INFO	*)lpParameter;					
	
	WaitTime = INFINITE;
	
	while (TRUE) {		
		Ret	= WaitForSingleObject(gp_nleddrvrInfo->hUpdateLedThreadEvent[p->LedNum], WaitTime);

		if (gp_nleddrvrInfo->bStopLedThread[p->LedNum])
			break;
			
		if (Ret == WAIT_OBJECT_0) {	
			if (p->OffOnBlink == NLED_BLINK) {
				OnTime = p->OnTime / 1000;
				if(p->OffTime!=INFINITE)
				OffTime	= p->OffTime / 1000;
				else
					OffTime = INFINITE;
				bLedOn = TRUE;
				WaitTime = OnTime;
				gp_nleddrvrInfo->pEioReg->rGPFDAT&=~(1<<(p->LedNum+4));
			} else {
				WaitTime = INFINITE;
				
				 if (p->OffOnBlink == NLED_ON) {
					gp_nleddrvrInfo->pEioReg->rGPFDAT&=~(1<<(p->LedNum+4));
				 } else if(p->OffOnBlink == NLED_OFF) {
					gp_nleddrvrInfo->pEioReg->rGPFDAT|=(1<<(p->LedNum+4));
				 }	
			}				
		} else {
			if (!bLedOn) {
				 gp_nleddrvrInfo->pEioReg->rGPFDAT&=~(1<<(p->LedNum+4));
								 
				bLedOn = TRUE;
				WaitTime = OnTime;
			} else {
				 gp_nleddrvrInfo->pEioReg->rGPFDAT|=(1<<(p->LedNum+4));
				
				bLedOn = FALSE;
				WaitTime = OffTime;
			}				
		}
	}

	return 0;
}

//------------------------------------------------------------------------------
//
// Function: NLedDriverInitialize
//
// The NLED	MDD	calls this routine to initialize the underlying	NLED hardware.
// This	routine	should return TRUE if successful.  If there's a	problem
// it should return	FALSE and call SetLastError() to pass back the reason
// for the failure.
//
// Parameters:
//		None.
//
// Returns:
//		TRUE indicates success. FALSE indicates failure.
//
//------------------------------------------------------------------------------
BOOL WINAPI	NLedDriverInitialize(VOID)
{
	PHYSICAL_ADDRESS phyAddr;
	
	DEBUGMSG(ZONE_PDD, (_T("NLedDriverInitialize: invoked\r\n")));

	// Alloc driver	struct
	gp_nleddrvrInfo	= (NLED_DRVR_INFO *)LocalAlloc(LPTR, sizeof(NLED_DRVR_INFO));
	if (!gp_nleddrvrInfo) {
		DEBUGMSG(ZONE_ERROR, (_T("NLedDriverInitialize: LocalAlloc failed!\r\n")));
		return FALSE;
	}
	
	// Map access to EIO register area
	phyAddr.QuadPart = IOP_PHY_BASE;
	gp_nleddrvrInfo->pEioReg = (IOPreg *)MmMapIoSpace(phyAddr, 
		sizeof(IOPreg), FALSE);
	if (!gp_nleddrvrInfo->pEioReg) {
		DEBUGMSG(ZONE_ERROR, (_T("NLedDriverInitialize: EIO IO0 NULL pointer!\r\n")));
		goto exitInit;
	}

	// Init	LED3 HW and globals
	gp_nleddrvrInfo->pEioReg->rGPFCON = (gp_nleddrvrInfo->pEioReg->rGPFCON & (~(0xff<<8)))|(0x55<<8);	//set GPF4,5,6,7 output.
      gp_nleddrvrInfo->pEioReg->rGPFUP  |= (0xf<<4);
	gp_nleddrvrInfo->pEioReg->rGPFDAT |= (0xf<<4);

	for(int i=NLED1;i<NLED_MAX;i++)
	{
		gp_nleddrvrInfo->curSetting[i].LedNum			= i;
		gp_nleddrvrInfo->curSetting[i].TotalCycleTime	= 0;
		gp_nleddrvrInfo->curSetting[i].OffOnBlink		= 0;
		gp_nleddrvrInfo->curSetting[i].OnTime			= 0;
		gp_nleddrvrInfo->curSetting[i].OffTime			= 0;
		gp_nleddrvrInfo->curSetting[i].MetaCycleOn		= 0;
		gp_nleddrvrInfo->curSetting[i].MetaCycleOff		= 0;
		gp_nleddrvrInfo->bStopLedThread[i]				= FALSE;
		gp_nleddrvrInfo->hLedThread[i]					= NULL;
		gp_nleddrvrInfo->hUpdateLedThreadEvent[i]		= CreateEvent(NULL, FALSE, FALSE, NULL);
		
		if (!gp_nleddrvrInfo->hUpdateLedThreadEvent[i]) {
			DEBUGMSG(ZONE_ERROR, (_T("NLedDriverInitialize: Failed to	create event\r\n")));
			goto exitInit;
		}

		gp_nleddrvrInfo->hLedThread[i] = CreateThread(NULL,	0, (LPTHREAD_START_ROUTINE)LedThread,
			&gp_nleddrvrInfo->curSetting[i], 0, NULL);		
		if (!gp_nleddrvrInfo->hLedThread[i]) {
			DEBUGMSG(ZONE_ERROR, (_T("NLedDriverInitialize: Failed to	create thread\r\n")));
			goto exitInit;
		}
	}
	
	return TRUE;

exitInit:

	for (UINT i=0; i<NLED_MAX; i++) {
		if (gp_nleddrvrInfo->hUpdateLedThreadEvent[i])
			CloseHandle(gp_nleddrvrInfo->hUpdateLedThreadEvent[i]);
		
		if (gp_nleddrvrInfo->hLedThread[i])
			CloseHandle(gp_nleddrvrInfo->hLedThread[i]);			
	}

	if (gp_nleddrvrInfo->pEioReg) {
		MmUnmapIoSpace(gp_nleddrvrInfo->pEioReg, sizeof(IOPreg));
		gp_nleddrvrInfo->pEioReg = NULL;
	}
		
	if (gp_nleddrvrInfo) {
		LocalFree(gp_nleddrvrInfo);
		gp_nleddrvrInfo	= NULL;
	}

	return FALSE;
}

//------------------------------------------------------------------------------
//
// Function: NLedDriverDeInitialize
//
// The NLED	MDD	calls this routine to deinitialize the underlying NLED
// hardware	as the NLED	driver is unloaded.	 It	should return TRUE if 
// successful.	If there's a problem this routine should return	FALSE 
// and call	SetLastError() to pass back	the	reason for the failure.
//
// Parameters:
//		None.
//
// Returns:
//		TRUE indicates success. FALSE indicates failure.
//
//------------------------------------------------------------------------------
BOOL WINAPI	NLedDriverDeInitialize(VOID)
{
	DEBUGMSG(ZONE_PDD, (_T("NLedDriverDeInitialize:	invoked\r\n")));

	for (UINT i=0; i<NLED_MAX; i++) {
		gp_nleddrvrInfo->bStopLedThread[i] = TRUE;
	
		SetEvent(gp_nleddrvrInfo->hUpdateLedThreadEvent[i]);
		
		if (gp_nleddrvrInfo->hUpdateLedThreadEvent[i])
			CloseHandle(gp_nleddrvrInfo->hUpdateLedThreadEvent[i]);
			
		if (gp_nleddrvrInfo->hLedThread[i])
			CloseHandle(gp_nleddrvrInfo->hLedThread[i]);
	}
	 
	if (gp_nleddrvrInfo->pEioReg) {
		MmUnmapIoSpace(gp_nleddrvrInfo->pEioReg, sizeof(IOPreg));
		gp_nleddrvrInfo->pEioReg = NULL;
	}

	if (gp_nleddrvrInfo) {
		LocalFree(gp_nleddrvrInfo);
		gp_nleddrvrInfo	= NULL;
	}

	return TRUE;
}

//------------------------------------------------------------------------------
//
// Function: NLedDriverGetDeviceInfo
//
// This	routine	retrieves information about	the	NLED device(s) that	
// this	driver supports.  The nInfoId parameter	indicates what specific	
// information is being queried	and	pOutput	is a buffer	to be filled in. 
// The size	of pOutput depends on the type of data being requested.	 This 
// routine returns TRUE	if successful, or FALSE	if there's a problem --	in
// which case it also calls	SetLastError() to pass back	more complete
// error information.  The NLED	MDD	invokes	this routine when an application
// calls NLedGetDeviceInfo().
//
// Parameters:
//		nInfoId
//			[in] The nInfoId parameter indicates what specific information
//			is being queried.
//		pOutput
//			[out] The pOutput is a buffer to be filled in.
//
// Returns:
//		TRUE indicates success. FALSE indicates failure.
//
//------------------------------------------------------------------------------
BOOL WINAPI	NLedDriverGetDeviceInfo(INT nInfoId, PVOID pOutput)
{
	BOOL fOk = TRUE;
	SETFNAME(_T("NLedDriverGetDeviceInfo"));

	if (!pOutput) {
		DEBUGMSG(ZONE_WARN, (_T("%s: invalid pOutput\r\n"), pszFname));
		return FALSE;
	}
		
	switch (nInfoId) {
		case NLED_COUNT_INFO_ID: {
			struct NLED_COUNT_INFO *p =	(struct	NLED_COUNT_INFO	*)pOutput;
			DEBUGMSG(ZONE_PDD, (_T("NLedDriverGetDeviceInfo: NLED_COUNT_INFO_ID\r\n")));
			__try {
				p->cLeds = NLED_MAX;
			} __except(EXCEPTION_EXECUTE_HANDLER) {
				SetLastError(ERROR_INVALID_PARAMETER);
				fOk	= FALSE;
			}
			break;
		}
		
		case NLED_SUPPORTS_INFO_ID: {
			struct NLED_SUPPORTS_INFO *p = (struct NLED_SUPPORTS_INFO *)pOutput;
			DEBUGMSG(ZONE_PDD, (_T("NLedDriverGetDeviceInfo: NLED_SUPPORTS_INFO_ID\r\n")));
			__try {
				if (p->LedNum < NLED_MAX) {
					p->lCycleAdjust				= 1000;
					p->fAdjustTotalCycleTime	= FALSE;
					p->fAdjustOnTime			= FALSE;
					p->fAdjustOffTime			= FALSE;
					p->fMetaCycleOn				= FALSE;
					p->fMetaCycleOff			= FALSE;
				} else {
				   SetLastError(ERROR_INVALID_PARAMETER);
					fOk = FALSE;
				}
			} __except(EXCEPTION_EXECUTE_HANDLER) {
				SetLastError(ERROR_INVALID_PARAMETER);
				fOk	= FALSE;
			}
			break;
		}
		
		case NLED_SETTINGS_INFO_ID: {
			struct NLED_SETTINGS_INFO *p = (struct NLED_SETTINGS_INFO *)pOutput;
			DEBUGMSG(ZONE_PDD, (_T("NLedDriverGetDeviceInfo: NLED_SETTINGS_INFO_ID\r\n")));
			__try {
				if (p->LedNum < NLED_MAX) {
					memcpy(p, &gp_nleddrvrInfo->curSetting[p->LedNum], sizeof(NLED_SETTINGS_INFO));
				} else {
					SetLastError(ERROR_INVALID_PARAMETER);
					fOk	= FALSE;
				}
			} __except(EXCEPTION_EXECUTE_HANDLER) {
				SetLastError(ERROR_INVALID_PARAMETER);
				fOk	= FALSE;
			}
			break;
		}
		
		default:
			DEBUGMSG(ZONE_ERROR, (_T("NLedDriverGetDeviceInfo: ERROR_INVALID_PARAMETER\r\n")));
			SetLastError(ERROR_INVALID_PARAMETER);
			fOk	= FALSE;
			break;
	}

	DEBUGMSG(ZONE_PDD, (_T("%s: returning %d\r\n"), pszFname, fOk));
	return (fOk);
}

//------------------------------------------------------------------------------
//
// Function: NLedDriverSetDevice
//
// This	routine	changes	the	configuration of an	LED.  The nInfoId parameter
// indicates what kind of configuration	information	is being changed.  
// Currently only the NLED_SETTINGS_INFO_ID	value is supported.	 The pInput
// parameter points	to a buffer	containing the data	to be updated.	The	size
// of the buffer depends on	the	value of nInfoId.  This	routine	returns	TRUE
// if successful or	FALSE if there's a problem -- in which case	it also	calls
// SetLastError().	The	NLED MDD invokes this routine when an application  
// calls NLedSetDevice().
//
// Parameters:
//		nInfoId
//			[in] The nInfoId parameter indicates what kind of configuration
//			information	is being changed.
//		pInput
//			[in] The pInput parameter points to a buffer containing the
//			data to be updated.
//
// Returns:
//		TRUE indicates success. FALSE indicates failure.
//
//------------------------------------------------------------------------------
BOOL WINAPI	NLedDriverSetDevice(INT nInfoId, PVOID pInput)
{
	BOOL fOk = TRUE;
	SETFNAME(_T("NLedDriverSetDevice"));

	if (nInfoId == NLED_SETTINGS_INFO_ID && pInput) {
		struct NLED_SETTINGS_INFO *p = (struct NLED_SETTINGS_INFO *)pInput;
	//	RETAILMSG(1, (TEXT("NLedDriverSetDevice: NLED_SETTINGS_INFO_ID led_num=%d,offonblick=%d,ontime=%d,offtime=%d\r\n"),p->LedNum,p->OffOnBlink,p->OnTime,p->OffTime));
		__try {
			NLED_SETTINGS_INFO prevSetting;
			prevSetting	= gp_nleddrvrInfo->curSetting[p->LedNum];	// Keep a copy of previous nledrvr settings
			memcpy(&gp_nleddrvrInfo->curSetting[p->LedNum],	p, sizeof(NLED_SETTINGS_INFO));
			fOk	= SetLedHw(p);
			if (!fOk) {
				memcpy(&gp_nleddrvrInfo->curSetting[p->LedNum],	&prevSetting, sizeof(NLED_SETTINGS_INFO));
				SetLastError(ERROR_INVALID_PARAMETER);
				RETAILMSG(1, (TEXT("NLedDriverSetDevice: NLED_SETTINGS_INFO_ID,led_num=%d,offonblick=%d,ontime=%d,offtime=%d\r\n"),p->LedNum,p->OffOnBlink,p->OnTime,p->OffTime));
			}				
		} __except(EXCEPTION_EXECUTE_HANDLER) {
			SetLastError(ERROR_INVALID_PARAMETER);
			fOk	= FALSE;
		}
	} else {
		DEBUGMSG(ZONE_WARN,	(_T("%s: only NLED_SETTINGS_INFO_ID	is supported\r\n"),	pszFname));
		SetLastError(ERROR_INVALID_PARAMETER);
		fOk	= FALSE;
	}

	return fOk;
}


//------------------------------------------------------------------------------
//
// Function: NLedDriverPowerDown
//
// This	routine	is invoked by the driver MDD when the system suspends or
// resumes.
//
// Parameters:
//		power_down
//			[in] The power_down flag indicates whether the system is powering 
//			up or powering down.
//
// Returns:
//		None.
//
//------------------------------------------------------------------------------
VOID WINAPI	NLedDriverPowerDown(BOOL power_down)
{
	if (power_down) {
		DEBUGMSG(ZONE_PDD, (TEXT("NLedDriverPowerDown: power down\r\n")));

		// Get state of	LEDs before	power them down
		for(int i=NLED1;i<NLED_MAX;i++)
		gp_nleddrvrInfo->bLedState[i] = (gp_nleddrvrInfo->pEioReg->rGPFDAT&(1<<(i+4))) ?FALSE:TRUE;

		// Power down all LEDs		
		gp_nleddrvrInfo->pEioReg->rGPFDAT|=(0xf<<4);		  
	} else {
		DEBUGMSG(ZONE_PDD, (TEXT("NLedDriverPowerDown: power up\r\n")));

		// Restore as per settings before power	down.
		for(int i=NLED1;i<NLED_MAX;i++)
		{
			if (gp_nleddrvrInfo->bLedState[i])
				gp_nleddrvrInfo->pEioReg->rGPFDAT&=~(1<<(i+4));
		}
	}
}



⌨️ 快捷键说明

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