📄 snled.cpp
字号:
// Copyright (c) David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
Abstract:
Notes:
--*/
#include <windows.h>
#include <nled.h>
#include <led_drvr.h>
#include <types.h>
#include "bsp.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
#define NLED_MAX_LED 1 // Total number of notification LEDs supported
#define NLED_MAX_OFFONBLINK 2 // Max OffOnBlink value
//------------------------------------------------------------------------------
// Types
struct NLedPddParameters
{
HANDLE hNLedStopThreadEvent;
HANDLE hNLedThreadStoppedEvent;
BOOL bNledState;
BOOL bNLedDriverSetDeviceThreadState;
NLED_SETTINGS_INFO NLedSettingsInfo;
NLED_SUPPORTS_INFO NLedSupportsInfo;
};
//------------------------------------------------------------------------------
// Global Variables
static volatile GPIO_REG_T *g_pGPIORegs = NULL; // GPIO registers
static NLedPddParameters g_NLedPddParam[NLED_MAX_LED];
//------------------------------------------------------------------------------
// Local Functions
DWORD WINAPI NLedDriverSetDeviceThread(LPVOID lParam);
//-----------------------------------------------------------------------------
//
// Function: NLedDriverInitialize
//
// The NLED MDD calls this routine to initialize the underlying NLED hardware.
//
// Parameters:
// None
//
// Returns:
// This routine should return TRUE if successful. If there's a problem
// it should return FALSE
//
//-----------------------------------------------------------------------------
BOOL WINAPI
NLedDriverInitialize(VOID)
{
DEBUGMSG(ZONE_PDD, (_T("+NLedDriverInitialize\r\n")));
PHYSICAL_ADDRESS GPIO_Base = {PXA255_BASE_REG_PA_GPIO};
ASSERT( g_pGPIORegs == NULL );
g_pGPIORegs = (GPIO_REG_T *)MmMapIoSpace( GPIO_Base, sizeof(GPIO_REG_T), FALSE );
if ( !g_pGPIORegs )
{
return FALSE;
}
for(int i=0; i<NLED_MAX_LED; i++)
{
g_NLedPddParam[i].bNledState = FALSE;
g_NLedPddParam[i].bNLedDriverSetDeviceThreadState = FALSE;
g_NLedPddParam[i].hNLedStopThreadEvent = NULL;
g_NLedPddParam[i].hNLedThreadStoppedEvent = NULL;
g_NLedPddParam[i].NLedSettingsInfo.LedNum = 0;
g_NLedPddParam[i].NLedSettingsInfo.MetaCycleOff = 0;
g_NLedPddParam[i].NLedSettingsInfo.MetaCycleOn = 0;
g_NLedPddParam[i].NLedSettingsInfo.OffOnBlink = 0;
g_NLedPddParam[i].NLedSettingsInfo.OffTime = 0;
g_NLedPddParam[i].NLedSettingsInfo.OnTime = 0;
g_NLedPddParam[i].NLedSettingsInfo.TotalCycleTime = 0;
g_NLedPddParam[i].NLedSupportsInfo.LedNum = 0;
g_NLedPddParam[i].NLedSupportsInfo.fAdjustOffTime = TRUE;
g_NLedPddParam[i].NLedSupportsInfo.fAdjustOnTime = TRUE;
g_NLedPddParam[i].NLedSupportsInfo.fAdjustTotalCycleTime = FALSE;
g_NLedPddParam[i].NLedSupportsInfo.lCycleAdjust = 1000;
g_NLedPddParam[i].NLedSupportsInfo.fMetaCycleOff = FALSE;
g_NLedPddParam[i].NLedSupportsInfo.fMetaCycleOn = FALSE;
}
for(int i=0; i<NLED_MAX_LED; i++)
{
if((g_NLedPddParam[i].hNLedStopThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
{
while(i)
{
i--;
CloseHandle(g_NLedPddParam[i].hNLedStopThreadEvent);
}
DEBUGMSG(ZONE_PDD, (_T("NLedDriverInitialize: CreateEvent() hNLedStopThreadEvent Failed\r\n")));
return FALSE;
}
}
for(int i=0; i<NLED_MAX_LED; i++)
{
if((g_NLedPddParam[i].hNLedThreadStoppedEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
{
while(i)
{
i--;
CloseHandle(g_NLedPddParam[i].hNLedThreadStoppedEvent);
}
DEBUGMSG(ZONE_PDD, (_T("NLedDriverInitialize: CreateEvent() hNLedThreadStoppedEvent Failed\r\n")));
return FALSE;
}
}
DEBUGMSG(ZONE_PDD, (_T("-NLedDriverInitialize\r\n")));
return (TRUE);
}
//-----------------------------------------------------------------------------
//
// Function: NLedDriverDeInitialize
//
// This routine deinitializes the underlying NLED hardware as the NLED driver is unloaded.
//
// Parameters:
// None
//
// Returns:
// This routine returns TRUE if successful, or FALSE if there's a problem
//
//-----------------------------------------------------------------------------
BOOL WINAPI
NLedDriverDeInitialize(VOID)
{
DEBUGMSG(ZONE_PDD, (_T("+NLedDriverDeInitialize\r\n")));
for(int i=0; i<NLED_MAX_LED; i++) // Stop all threads
SetEvent(g_NLedPddParam[i].hNLedStopThreadEvent);
for(int i=0; i<NLED_MAX_LED; i++) // Wait for all threads to stop
{
if(g_NLedPddParam[i].bNLedDriverSetDeviceThreadState)
WaitForSingleObject(g_NLedPddParam[i].hNLedThreadStoppedEvent, INFINITE);
}
for(int i=0; i<NLED_MAX_LED; i++)
{
CloseHandle(g_NLedPddParam[i].hNLedThreadStoppedEvent);
CloseHandle(g_NLedPddParam[i].hNLedStopThreadEvent);
}
if ( g_pGPIORegs )
{
MmUnmapIoSpace((PVOID)g_pGPIORegs, sizeof(GPIO_REG_T));
g_pGPIORegs = NULL;
}
DEBUGMSG(ZONE_PDD, (_T("-NLedDriverDeInitialize\r\n")));
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.
//
// Parameters:
// InputParm
// [in] INT nInfoId
//
// OutputParm
// [out] PVOID pOutput
//
// Returns:
// This routine returns TRUE if successful, or FALSE if there's a problem
//
//-----------------------------------------------------------------------------
BOOL WINAPI
NLedDriverGetDeviceInfo(
INT nInfoId,
PVOID pOutput
)
{
DEBUGMSG(ZONE_PDD, (_T("+NLedDriverGetDeviceInfo\r\n")));
BOOL fOk = TRUE;
if(nInfoId == NLED_COUNT_INFO_ID)
{
struct NLED_COUNT_INFO *p = (struct NLED_COUNT_INFO*)pOutput;
p -> cLeds = NLED_MAX_LED;
}
else if (nInfoId == NLED_SUPPORTS_INFO_ID)
{
struct NLED_SUPPORTS_INFO *p = (struct NLED_SUPPORTS_INFO*)pOutput;
if(p->LedNum >= NLED_MAX_LED)
fOk = FALSE;
else
{
p->fAdjustOffTime = g_NLedPddParam[p->LedNum].NLedSupportsInfo.fAdjustOffTime;
p->fAdjustOnTime = g_NLedPddParam[p->LedNum].NLedSupportsInfo.fAdjustOnTime;
p->lCycleAdjust = g_NLedPddParam[p->LedNum].NLedSupportsInfo.lCycleAdjust;
p->fMetaCycleOff = g_NLedPddParam[p->LedNum].NLedSupportsInfo.fMetaCycleOff;
p->fMetaCycleOn = g_NLedPddParam[p->LedNum].NLedSupportsInfo.fMetaCycleOn;
p->fAdjustTotalCycleTime = g_NLedPddParam[p->LedNum].NLedSupportsInfo.fAdjustTotalCycleTime;
}
}
else if (nInfoId == NLED_SETTINGS_INFO_ID)
{
struct NLED_SETTINGS_INFO *p = (struct NLED_SETTINGS_INFO*)pOutput;
if(p->LedNum >= NLED_MAX_LED)
fOk = FALSE;
else
{
p->MetaCycleOff = g_NLedPddParam[p->LedNum].NLedSettingsInfo.MetaCycleOff;
p->MetaCycleOn = g_NLedPddParam[p->LedNum].NLedSettingsInfo.MetaCycleOn;
p->OffOnBlink = g_NLedPddParam[p->LedNum].NLedSettingsInfo.OffOnBlink;
p->OffTime = g_NLedPddParam[p->LedNum].NLedSettingsInfo.OffTime;
p->OnTime = g_NLedPddParam[p->LedNum].NLedSettingsInfo.OnTime;
p->TotalCycleTime = g_NLedPddParam[p->LedNum].NLedSettingsInfo.TotalCycleTime;
}
}
else
{
fOk = FALSE;
}
DEBUGMSG(ZONE_PDD, (_T("-NLedDriverGetDeviceInfo\r\n")));
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.
//
// Parameters:
// InputParm
// [in] INT nInfoId
// [in] PVOID pInput
//
// Returns:
// This routine returns TRUE if successful, or FALSE if there's a problem
//
//-----------------------------------------------------------------------------
BOOL WINAPI
NLedDriverSetDevice(
INT nInfoId,
PVOID pInput
)
{
DEBUGMSG(ZONE_PDD, (_T("+NLedDriverSetDevice\r\n")));
HANDLE hThread = NULL;
struct NLED_SETTINGS_INFO *pNledSettingsInfo = (struct NLED_SETTINGS_INFO*)pInput;
if(nInfoId != NLED_SETTINGS_INFO_ID)
{
DEBUGMSG(ZONE_PDD, (_T("NLedDriverSetDevice: Invalid nInfoId\r\n")));
return FALSE;
}
if(pNledSettingsInfo->LedNum >= NLED_MAX_LED) // Check LedNum validity
{
DEBUGMSG(ZONE_PDD, (_T("NLedDriverSetDevice: Invalid LedNum\r\n")));
return FALSE;
}
if(pNledSettingsInfo->OffOnBlink > NLED_MAX_OFFONBLINK) // Check OffOnBlink validity
{
DEBUGMSG(ZONE_PDD, (_T("NLedDriverSetDevice: Invalid OffOnBlink\r\n")));
return FALSE;
}
if(g_NLedPddParam[pNledSettingsInfo->LedNum].bNLedDriverSetDeviceThreadState)
{
SetEvent(g_NLedPddParam[pNledSettingsInfo->LedNum].hNLedStopThreadEvent);
DEBUGMSG(ZONE_PDD, (_T("NLedDriverSetDevice: WaitForSingleObject - hNLedThreadStoppedEvent\r\n")));
WaitForSingleObject(g_NLedPddParam[pNledSettingsInfo->LedNum].hNLedThreadStoppedEvent, INFINITE);
}
g_NLedPddParam[pNledSettingsInfo->LedNum].NLedSettingsInfo.LedNum = pNledSettingsInfo->LedNum;
g_NLedPddParam[pNledSettingsInfo->LedNum].NLedSettingsInfo.OffOnBlink = pNledSettingsInfo->OffOnBlink;
if(pNledSettingsInfo->OffOnBlink == 0) // OffOnBlink setting - 0 OFF
{
switch (pNledSettingsInfo->LedNum) {
case 0:
g_pGPIORegs->GPSR2 = NOTIFY_LED0_GPIO;
break;
default:
break;
}
g_NLedPddParam[pNledSettingsInfo->LedNum].bNledState = FALSE;
}
else if(pNledSettingsInfo->OffOnBlink == 1) // OffOnBlink setting - 1 ON
{
switch (pNledSettingsInfo->LedNum) {
case 0:
g_pGPIORegs->GPCR2 = NOTIFY_LED0_GPIO;
break;
default:
break;
}
g_NLedPddParam[pNledSettingsInfo->LedNum].bNledState = TRUE;
}
else // OffOnBlink setting - 2 BLINK
{
UINT Index = pNledSettingsInfo->LedNum;
g_NLedPddParam[Index].bNLedDriverSetDeviceThreadState = TRUE;
g_NLedPddParam[Index].NLedSettingsInfo = *(pNledSettingsInfo);
// Round up OnTime and OffTime values 100 millisecond at least
if(g_NLedPddParam[Index].NLedSettingsInfo.OnTime < 100000)
g_NLedPddParam[Index].NLedSettingsInfo.OnTime = 100000;
if(g_NLedPddParam[Index].NLedSettingsInfo.OffTime < 100000)
g_NLedPddParam[Index].NLedSettingsInfo.OffTime = 100000;
hThread = CreateThread(
NULL,
0,
NLedDriverSetDeviceThread,
&g_NLedPddParam[Index].NLedSettingsInfo, // Start routine parameter
0,
NULL
);
if (hThread == NULL)
{
g_NLedPddParam[Index].bNLedDriverSetDeviceThreadState = FALSE;
return FALSE;
}
CloseHandle(hThread);
}
DEBUGMSG(ZONE_PDD, (_T("-NLedDriverSetDevice\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: NLedDriverPowerDown
//
// This routine is invoked by the driver MDD when the system suspends or
// resumes. The power_down flag indicates whether the system is powering
// up or powering down.
//
// Parameters:
// InputParm
// [in] BOOL power_down
//
// Returns:
// None
//
//-----------------------------------------------------------------------------
VOID WINAPI
NLedDriverPowerDown(
BOOL power_down
)
{
DEBUGMSG(ZONE_PDD, (_T("+NLedDriverPowerDown\r\n")));
DEBUGMSG(ZONE_PDD, (_T("-NLedDriverPowerDown\r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: NLedDriverSetDeviceThread
//
// This routine is invoked by CreateThread() function in NLedDriverSetDevice when
// caller attempts to change the configuration of a notification LED to 'Blink' mode
//
// Parameters:
// InputParm
// [in] LPVOID lParam
//
// Returns:
// This routine returns 0
//
//-----------------------------------------------------------------------------
DWORD WINAPI NLedDriverSetDeviceThread(LPVOID lParam)
{
DEBUGMSG(ZONE_PDD, (_T("+NLedDriverSetDeviceThread\r\n")));
NLED_SETTINGS_INFO *pNledSettingsInfo = (struct NLED_SETTINGS_INFO*)lParam;
UINT Index = pNledSettingsInfo->LedNum;
DWORD OnTimeOut = (DWORD)(pNledSettingsInfo->OnTime/1000); // to convert micro to milli-seconds
DWORD OffTimeOut = (DWORD)(pNledSettingsInfo->OffTime/1000); // to convert micro to milli-seconds
while(1)
{
switch (Index) {
case 0:
g_pGPIORegs->GPSR2 = NOTIFY_LED0_GPIO;
break;
default:
break;
}
g_NLedPddParam[Index].bNledState = TRUE;
if(WaitForSingleObject(g_NLedPddParam[Index].hNLedStopThreadEvent, OnTimeOut) == WAIT_OBJECT_0)
break;
switch (Index) {
case 0:
g_pGPIORegs->GPCR2 = NOTIFY_LED0_GPIO;
break;
default:
break;
}
g_NLedPddParam[Index].bNledState = FALSE;
if(WaitForSingleObject(g_NLedPddParam[Index].hNLedStopThreadEvent, OffTimeOut) == WAIT_OBJECT_0)
break;
}
pNledSettingsInfo->LedNum = 0;
pNledSettingsInfo->MetaCycleOff = 0;
pNledSettingsInfo->MetaCycleOn = 0;
pNledSettingsInfo->OffOnBlink = 0;
pNledSettingsInfo->OffTime = 0;
pNledSettingsInfo->OnTime = 0;
pNledSettingsInfo->TotalCycleTime = 0;
SetEvent(g_NLedPddParam[Index].hNLedThreadStoppedEvent);
g_NLedPddParam[Index].bNLedDriverSetDeviceThreadState = FALSE;
DEBUGMSG(ZONE_PDD, (_T("-NLedDriverSetDeviceThread\r\n")));
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -