WINCE背光驱动
来源:互联网 发布:ubuntu恢复删除的文件 编辑:程序博客网 时间:2024/05/02 01:34
当你好好分析驱动中的以下这3个Event时:
g_evtSignal[0] = CreateEvent(NULL, FALSE, FALSE, szevtBacklightChange);
g_evtSignal[1] = CreateEvent(NULL, FALSE, FALSE, szevtUserInput);
g_evtSignal[BL_POWEREVT] = CreateEvent(NULL, FALSE, FALSE, szevtPowerChanged);
尤其是第二个,好像又没有问题。其实这个驱动大体是正确的,修改后的源程序(不完整严密,例如没有创建线程语句)如下:
// Globals
const TCHAR szevtBacklightChange[] = TEXT("BackLightChangeEvent");
const TCHAR szevtPowerChanged[] = TEXT("PowerChangedEvent");
const TCHAR szevtUserInput[] = TEXT("PowerManager/ActivityTimer/UserActivity");
const TCHAR szregRootKey[] = TEXT("ControlPanel//Backlight");
const TCHAR szregBatteryTimeout[] = TEXT("BatteryTimeout");
const TCHAR szregACTimeout[] = TEXT("ACTimeout");
const TCHAR szregBatteryAuto[] = TEXT("BacklightOnTap");
const TCHAR szregACAuto[] = TEXT("ACBacklightOnTap");
HANDLE g_evtSignal[NUM_EVENTS]; //NUM_EVENTS为3
volatile IOPreg * v_pIOPregs = (IOPreg * )IOP_BASE; /* GPIO 寄存器对应的虚拟地址 */
BLStruct g_BLInfo; // Global structure
void BL_On(BOOL bOn) // turn on/off the backlight
{
if(bOn)
{
if (g_BLInfo.m_dwStatus != BL_ON)
{
g_BLInfo.m_dwStatus = BL_ON;
v_pIOPregs->rGPBDAT&=0x6FF;//打开LED
RETAILMSG(1,(TEXT("!!!!!!!!!!!! BACKLIGHT ON !!!!!!!!!!!!/r/n")));
}
}
else
{
if (g_BLInfo.m_dwStatus != BL_OFF)
{
g_BLInfo.m_dwStatus = BL_OFF;
v_pIOPregs->rGPBDAT|=0x100;//关闭LED
RETAILMSG(1,(TEXT("!!!!!!!!!!!! BACKLIGHT OFF !!!!!!!!!!!!/r/n")));
}
}
}
void BL_PowerOn(BOOL bInit) // restore power to the backlight
{
BL_On(TRUE);
}
BOOL BacklightInitialize() // Perform all one-time initialization of the backlight
{
BOOL bRet = TRUE;
RETAILMSG(1, (TEXT("BacklightInitialize/r/n")));
BL_PowerOn(TRUE);
v_pIOPregs->rGPBCON &=0x3C03FF;
v_pIOPregs->rGPBCON |=0x15400;
v_pIOPregs->rGPBUP &=0x61F; //开背光
return bRet;
}
void BL_ReadRegistry(BLStruct *pBLInfo) // Utility function to read from registry for the parameters
{
HKEY hKey;
LONG lResult;
DWORD dwType;
DWORD dwVal;
DWORD dwLen;
lResult = RegOpenKeyEx(HKEY_CURRENT_USER, szregRootKey, 0, KEY_ALL_ACCESS, &hKey);
if(ERROR_SUCCESS == lResult)
{
dwType = REG_DWORD;
dwLen = sizeof(DWORD);
lResult = RegQueryValueEx(hKey, szregBatteryTimeout, NULL, &dwType, (LPBYTE)&dwVal, &dwLen);
if(ERROR_SUCCESS == lResult)
{
pBLInfo->m_dwBatteryTimeout = dwVal;
}
lResult = RegQueryValueEx(hKey, szregACTimeout, NULL, &dwType, (LPBYTE)&dwVal, &dwLen);
if(ERROR_SUCCESS == lResult)
{
pBLInfo->m_dwACTimeout = dwVal;
}
lResult = RegQueryValueEx(hKey, szregBatteryAuto, NULL, &dwType, (LPBYTE)&dwVal, &dwLen);
if(ERROR_SUCCESS == lResult)
{
pBLInfo->m_bBatteryAuto = (BOOL) dwVal;
}
lResult = RegQueryValueEx(hKey, szregACAuto, NULL, &dwType, (LPBYTE)&dwVal, &dwLen);
if(ERROR_SUCCESS == lResult)
{
pBLInfo->m_bACAuto = (BOOL) dwVal;
}
RegCloseKey(hKey);
}
else
{
RETAILMSG(1, (TEXT("BAK : HKEY_CURRENT_USER//%s key doesn't exist!/r/n"), szregRootKey));
}
}
BOOL BL_Init() // initialize the backlight
{
// Set up all the events we need.
g_evtSignal[0] = CreateEvent(NULL, FALSE, FALSE, szevtBacklightChange);
g_evtSignal[1] = CreateEvent(NULL, FALSE, FALSE, szevtUserInput);
g_evtSignal[BL_POWEREVT] = CreateEvent(NULL, FALSE, FALSE, szevtPowerChanged);
if(!g_evtSignal[0] || !g_evtSignal[1] || !g_evtSignal[2])
{
BL_Deinit();
return FALSE;
}
DEBUGMSG (1,(TEXT("BL_Init() and SetGPIO/n/r")));
return TRUE;
}
void BL_Deinit() // uninitialize the backlight
{
int i;
RETAILMSG(1, (TEXT("BAK : BL_Deinit!/r/n")));
for(i=0; i<NUM_EVENTS; i++) // Clean up
{
if(g_evtSignal[i])
{
CloseHandle(g_evtSignal[i]);
}
}
}
/*The backlight handling is done by a thread, which monitors those three event and performs some actions based on the parameters specified */
DWORD BL_MonitorThread(PVOID pParms) // backlight service thread
{
DWORD dwResult;
DWORD dwTimeout;
g_BLInfo.m_bACAuto = TRUE;
g_BLInfo.m_bBatteryAuto = TRUE;
g_BLInfo.m_dwBatteryTimeout = 20; // 20 Seconds
g_BLInfo.m_dwACTimeout = 60; // 1 minutes
BL_ReadRegistry(&g_BLInfo); // Now read from the registry to see what they say
if(!BL_Init()) // Initialize BL
{
RETAILMSG(1, (TEXT("BL_Init() Failed! Exit from BL_MonitorThread!/r/n")));
return 0;
}
while(1)
{
__try
{
// If we are using AC now, use m_dwACTimeout as the timeout,otherwise use m_dwBatteryTimeout
if(IsACOn())
{
dwTimeout = g_BLInfo.m_dwACTimeout * 1000;
}
else
{
dwTimeout = g_BLInfo.m_dwBatteryTimeout * 1000;
}
// However, if user wants BL on all the time, we have to let him
// do that. Or if we come back here, and BL is off, we want to
// put this thread to sleep until other event happens.
if(dwTimeout == 0 || g_BLInfo.m_dwStatus == BL_OFF)
{
dwTimeout = INFINITE;
}
// Now let's wait for either there is an update on registry, or
// there is user action on the device, or there is activity on
// AC power supply.
dwResult = WaitForMultipleObjects(NUM_EVENTS, &g_evtSignal[0], FALSE, dwTimeout);
if(WAIT_OBJECT_0 == dwResult) //背光时延被改变
{
// All we need to do is to read from registry and update the tick count
BL_ReadRegistry(&g_BLInfo);
// Always turn on the Backlight after a change to registry
BL_On(TRUE);
}
else if(dwResult == WAIT_OBJECT_0+1)
{
//User activity, depending on the situation, we may / may not update the tick count
if(IsACOn())
{
if(g_BLInfo.m_bACAuto)
{
BL_On(TRUE);
}
}
else
{
if(g_BLInfo.m_bBatteryAuto)
{
BL_On(TRUE);
}
}
}
else if(dwResult == WAIT_OBJECT_0+2)
{
// When AC is plugged or un-plugged, we don't really need to do anything
// We continue the loop. The correct timeout value will be assigned at
// the top of the while loop.
RETAILMSG(1, (TEXT("BackLight Thread: power changed!/r/n")));
}
else if(dwResult == WAIT_TIMEOUT)
{
// Time out, let's turn the device off
RETAILMSG(1, (TEXT("Timeout, turn off the backlight!/r/n")));
BL_On(FALSE);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RETAILMSG(1, (TEXT("an exception is raised in BL_MonitorThread... /r/n")));
}
} //while
}
另补充对应的IOCTL处理函数:
BOOL BKL_IOControl(DWORD dwOpenContext, DWORD dwIoControlCode, LPBYTE lpInBuf, DWORD nInBufSize, LPBYTE lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
DWORD dwErr = ERROR_INVALID_PARAMETER;
// Verify context
if(! dwOpenContext)
{
RETAILMSG(ZONE_ERROR, (L"ERROR: BKL_Deinit: "L"Incorrect context paramer/r/n" ));
return FALSE;
}
switch (dwIoControlCode)
{
case IOCTL_POWER_CAPABILITIES:
RETAILMSG(ZONE_BACKLIGHT, (TEXT("BKL: IOCTL_POWER_CAPABILITIES/r/n")));
................;
break;
case IOCTL_POWER_QUERY: // determines whether changing power state is feasible
RETAILMSG(ZONE_BACKLIGHT,(TEXT("BKL: Received IOCTL_POWER_QUERY/r/n")));
...............;
break;
case IOCTL_POWER_SET: // requests a change from one device power state to another
RETAILMSG(ZONE_BACKLIGHT,(TEXT("BKL: Received IOCTL_POWER_SET/r/n")));
..............;
break;
case IOCTL_POWER_GET: // gets the current device power state
RETAILMSG(ZONE_BACKLIGHT,(TEXT("BKL: Received IOCTL_POWER_GET/r/n")));
..............;
break;
default:
dwErr = BacklightIOControl(pBKLinfo->dwPddContext, dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned);
RETAILMSG(ZONE_BACKLIGHT,(TEXT("BacklightIOControl IOCTL code %u/r/n"), dwIoControlCode));
break;
}
}
//对补充的IOCTL码处理
DWORD BacklightIOControl(DWORD dwOpenContext, DWORD dwIoControlCode, LPBYTE lpInBuf, DWORD nInBufSize, LPBYTE lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
DWORD ret = ERROR_SUCCESS;
switch(dwIoControlCode)
{
case BLK_IOCTL_SET_BRIGHTNESS:
..........................;
break;
case BLK_IOCTL_GET_BRIGHTNESS:
..........................;
break;
case BLK_IOCTL_GET_MINFREQ:
..........................;
break;
case BLK_IOCTL_SET_MINFREQ:
..........................;
break;
default:
ret = !ERROR_SUCCESS;
break;
}
return ret;
}
参考原文:http://blog.csdn.net/cy757/archive/2008/08/07/2783730.aspx
- WINCE背光驱动
- WINCE背光驱动
- 2416 wince 背光驱动
- wince 背光驱动u
- wince + 6410 背光驱动记录
- WINCE基于PWM实现的背光驱动
- wince下背光驱动资料总结
- 基于S3C2450 + WINCE的背光驱动及背光亮度调节应用程序移植详解之驱动篇
- 四极管:WINCE基于PWM实现的背光驱动
- WINCE基于PWM实现的背光驱动---转自LoongEmbedded
- 背光驱动
- 基于S3C2450 + WINCE的背光驱动及背光亮度调节应用程序移植详解之驱动篇[原创]
- WinCE 背光显示bug
- WinCE 背光调节
- wince中的背光灯控制
- wince中的背光灯控制
- wince中的背光灯控制
- wince中的背光灯控制
- CheckedListBox用法
- oracle 日期函数介绍
- WINCE 音频驱动之一:分类
- php 的webservice类库NuSoap介绍
- WinCE平台上的DMA
- WINCE背光驱动
- WINCE的电源管理
- TextBox文本框中如何换行
- WIFI之四:WINCE 500上WIFI工具的编写
- 计算机类核心期刊排名
- 使用DATE时注意
- WIFI之三:WIN MOBILE平台上的88W8688驱动
- 黑马程序员-java-枚举
- 基于线程的WINCE测试程序