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 + -
显示快捷键?