基于S3C2450 + WINCE的背光驱动及背光亮度调节应用程序移植详解之驱动篇

来源:互联网 发布:中印军力 知乎 编辑:程序博客网 时间:2024/05/17 23:34

 背光驱动程序设计

 

1. 这里硬件接口使用S3C2450的GPB1,即定时器1.

    定时器的输入频率 = PCLK /{prescaler value + 1} / {divider value}。

    首先设置prescaler value:

   

[cpp] view plaincopy
  1. static void BAK_SetPrescaleAndMux( DWORD v_Prescale, DWORD v_Mux )  
  2. {  
  3.     // Set prescale.  
  4.     if(v_Prescale<=255)  
  5.     {  
  6.         v_pPWMRegs->TCFG0 = v_pPWMRegs->TCFG0 & (~0xff) | v_Prescale;  
  7.     }  
  8.     // Set divider value.Timer1 is used  
  9.     switch(v_Mux)  
  10.     {  
  11.     case 1:// 1/2  
  12.         v_pPWMRegs->TCFG1 = v_pPWMRegs->TCFG1 & (~0xF0) | (0x0<<4);  
  13.         break;  
  14.     case 2:// 1/4  
  15.         v_pPWMRegs->TCFG1 = v_pPWMRegs->TCFG1 & (~0xF0) | (0x1<<4);  
  16.         break;  
  17.     case 3:// 1/8  
  18.         v_pPWMRegs->TCFG1 = v_pPWMRegs->TCFG1 & (~0xF0) | (0x2<<4);  
  19.         break;  
  20.     case 4:// 1/16  
  21.         v_pPWMRegs->TCFG1 = v_pPWMRegs->TCFG1 & (~0xF0) | (0x3<<4);  
  22.         break;  
  23.     case 5:  
  24.     default:// External TCLK0  
  25.         v_pPWMRegs->TCFG1 = v_pPWMRegs->TCFG1 & (~0xF0) | (0x4<<4);  
  26.         break;  
  27.     }  
  28. }  

    然后设置divider value:

   

[cpp] view plaincopy
  1. static  void BAK_SetTCNTB( DWORD v_Tcntb)  
  2. {  
  3.     if(v_Tcntb<=0xffff)  
  4.     {  
  5.         v_pPWMRegs->TCNTB1 = v_Tcntb;  
  6.     }  
  7. }  

2.    接着设置TOUT1的定时器PWM脉宽:

[cpp] view plaincopy
  1. static void BAK_SetTCMPB( DWORD v_Tcmpb)  
  2. {  
  3.     if(v_Tcmpb<=0xffff)  
  4.     {  
  5.         v_pPWMRegs->TCMPB1 = v_Tcmpb;  
  6.     }  
  7. }  

 3.   设置完这些就可以开启TOUT1了。代码如下:

[cpp] view plaincopy
  1. static void BAK_StartPwmTimer( void )  
  2. {  
  3.     // Set GPB1 to TOUT1.  
  4.     v_pIOPregs->GPBCON &= ~(0x03<<2);  
  5.     v_pIOPregs->GPBCON |= (0x02<<2);  
  6.     // Stop pwm timer 1, first.  
  7.     v_pPWMRegs->TCON &= ~(0xF<<8);  
  8.     v_pPWMRegs->TCON |= (0x6<<8);  // 这里0x2<<8也OK吧!!!!!  
  9.     // Start it again.    
  10.     v_pPWMRegs->TCON &= ~(0xF<<8);  
  11.     v_pPWMRegs->TCON |= (0x9<<8);  
  12. }  

 4.   背光亮度调节代码如下(将亮度设置为10个级别):

[cpp] view plaincopy
  1. static void BAK_AdjuctBacklightLevel(DWORD v_Level)  
  2. {  
  3.     if((v_Level>=BAK_LEVEL_MIN)&&(v_Level<=BAK_LEVEL_MAX))// v_Level=[1:10]  
  4.     {  
  5.         l_dwBackLightLevel = v_Level;  
  6.         BAK_SetTCMPB((l_dwTcntb * la_dwLevel[v_Level-1])/100);  
  7.     }  
  8. }  

5.以上事情都做完了后,就可以编写通用的流接口程序了。由于程序比较简单,这里

仅贴上XXX_IOControl的代码如下:

[cpp] view plaincopy
  1. BOOL BAK_IOControl(  
  2.         DWORD hOpenContext,  
  3.         DWORD dwCode,  
  4.         PBYTE pBufIn,  
  5.         DWORD dwLenIn,  
  6.         PBYTE pBufOut,  
  7.         DWORD dwLenOut,  
  8.         PDWORD pdwActualOut   
  9.         )  
  10. {  
  11.     DWORD dwErr = ERROR_INVALID_PARAMETER;  
  12.     BOOL bRc;  
  13.       
  14.     RETAILMSG(lqm_bakdbg, (TEXT("[lqm:BKL] IOCTL code  = %d/r/n"), dwCode));  
  15.     switch (dwCode)   
  16.     {  
  17.     case IOCTL_POWER_CAPABILITIES:  // determines device-specific capabilities  
  18.         RETAILMSG(DBGBAK, (TEXT("[lqm:BKL] IOCTL_POWER_CAPABILITIES/r/n")));  
  19.         if (pBufOut && dwLenOut >= sizeof (POWER_CAPABILITIES) && pdwActualOut)   
  20.         {  
  21.             __try   
  22.             {  
  23.                 PPOWER_CAPABILITIES PowerCaps = (PPOWER_CAPABILITIES)pBufOut;  
  24.                 // Right now supports D0 (permanently on) and D4(off) only.  
  25.                 memset(PowerCaps, 0, sizeof(*PowerCaps));  
  26.                 PowerCaps->DeviceDx = 0x12; //support D0, D1,  D4  
  27.                 *pdwActualOut = sizeof(*PowerCaps);  
  28.                 bRc = TRUE;  
  29.                 dwErr = ERROR_SUCCESS;  
  30.             }  
  31.             __except(EXCEPTION_EXECUTE_HANDLER)   
  32.             {  
  33.                 RETAILMSG(DBGBAK1, (TEXT("<BKL> exception in ioctl/r/n")));  
  34.             }  
  35.         }  
  36.         else  
  37.             bRc = FALSE;  
  38.         break;  
  39.   
  40.     case IOCTL_POWER_QUERY: // determines whether changing power state is feasible  
  41.         RETAILMSG(DBGBAK, (TEXT("<BKL> Received IOCTL_POWER_QUERY/r/n")));  
  42.         if (pBufOut && dwLenOut >= sizeof(CEDEVICE_POWER_STATE))   
  43.         {  
  44.             // Return a good status on any valid query, since we are always ready to  
  45.             // change power states (if asked for state we don't support, we move to next highest, eg D3->D4).  
  46.             __try   
  47.             {  
  48.                 CEDEVICE_POWER_STATE ReqDx = *(PCEDEVICE_POWER_STATE)pBufOut;  
  49.   
  50.                 if (VALID_DX(ReqDx))   
  51.                 {  
  52.                     // This is a valid Dx state so return a good status.  
  53.                     bRc = TRUE;  
  54.                     dwErr = ERROR_SUCCESS;  
  55.                 }  
  56.                 else  
  57.                 {  
  58.                     bRc = FALSE;  
  59.                 }  
  60.                 RETAILMSG(DBGBAK, (TEXT("<BKL> IOCTL_POWER_QUERY %s/r/n"), dwErr == ERROR_SUCCESS ? (TEXT("succeeded")) : (TEXT("failed")) ));  
  61.             }  
  62.             __except(EXCEPTION_EXECUTE_HANDLER)   
  63.             {  
  64.                 RETAILMSG(DBGBAK1, (TEXT("<BKL> Exception in ioctl/r/n")));  
  65.             }  
  66.         }  
  67.         else          
  68.             bRc = FALSE;  
  69.         break;  
  70.   
  71.     case IOCTL_POWER_SET: // requests a change from one device power state to another  
  72.          RETAILMSG(lqm_bakdbg, (TEXT("[lqm:BKL] Received IOCTL_POWER_SET/r/n")));  
  73.         if (pBufOut && dwLenOut >= sizeof(CEDEVICE_POWER_STATE))   
  74.         {  
  75.             __try   
  76.             {  
  77.                 CEDEVICE_POWER_STATE ReqDx = *(PCEDEVICE_POWER_STATE)pBufOut;  
  78.   
  79.                 if (VALID_DX(ReqDx))   
  80.                 {  
  81.                     RETAILMSG(lqm_bakdbg,(TEXT("[lqm:BKL] Received IOCTL_POWER_SET=%d/r/n"), ReqDx));  
  82.                     if( ReqDx == (CEDEVICE_POWER_STATE)D2 || ReqDx == (CEDEVICE_POWER_STATE)D3)  
  83.                     bklStatus = (CEDEVICE_POWER_STATE)D4;  
  84.                     else  
  85.                     bklStatus = ReqDx;  
  86.   
  87.                     //SetEvent(g_evtBacklight);  
  88.                     // 调整亮度值后调用函数执行调整  
  89.                     BAK_hw_setBL();  
  90.                     *(PCEDEVICE_POWER_STATE) pBufOut = bklStatus;  
  91.                     *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);  
  92.                     bRc = TRUE;  
  93.                     dwErr = ERROR_SUCCESS;  
  94.                     RETAILMSG(lqm_bakdbg, (TEXT("[lqm:BKL] IOCTL_POWER_SET to D%d /r/n"), ReqDx));  
  95.                 }  
  96.                 else   
  97.                 {  
  98.                     bRc = FALSE;  
  99.                     RETAILMSG(DBGBAK1, (TEXT("<BKL> Invalid state request D%d/r/n"), ReqDx));  
  100.                 }  
  101.             }  
  102.             __except(EXCEPTION_EXECUTE_HANDLER)   
  103.             {  
  104.                 RETAILMSG(DBGBAK1, (TEXT("<BKL> Exception in ioctl/r/n")));  
  105.             }  
  106.         }  
  107.         else      
  108.         {     
  109.             bRc = FALSE;  
  110.         }  
  111.         break;  
  112.       
  113.     case IOCTL_POWER_GET: // gets the current device power state  
  114.         RETAILMSG(DBGBAK, (TEXT("<BKL> Received IOCTL_POWER_GET/r/n/n")));      
  115.         if (pBufOut != NULL && dwLenOut >= sizeof(CEDEVICE_POWER_STATE))   
  116.         {  
  117.             __try   
  118.             {  
  119.                 *(PCEDEVICE_POWER_STATE)pBufOut = getBacklightStatus();  
  120.   
  121.                 bRc = TRUE;  
  122.                 dwErr = ERROR_SUCCESS;  
  123.   
  124.                 RETAILMSG(DBGBAK, (TEXT("<BKL> IOCTL_POWER_GET: passing back %u/r/n"), getBacklightStatus()));  
  125.             }  
  126.             __except(EXCEPTION_EXECUTE_HANDLER)   
  127.             {  
  128.                 RETAILMSG(DBGBAK1, (TEXT("<BKL> Exception in ioctl/r/n")));  
  129.             }  
  130.         }  
  131.         else          
  132.             bRc = FALSE;  
  133.         break;  
  134.     // 背光亮度调节  
  135.     case IOCTL_BACKLIGHT_ADJUST:          
  136.          if (pBufOut != NULL && (dwLenOut>=sizeof(DWORD)))  
  137.          {  
  138.             DWORD dwBackLight = *((DWORD*)pBufOut);  
  139.             if((BAK_LEVEL_MAX <dwBackLight) || (BAK_LEVEL_MIN > dwBackLight ))  
  140.             {  
  141.                 *(DWORD*)pBufOut = ERROR_INVALID_PARAMETER;  
  142.                 *pdwActualOut = sizeof(DWORD);  
  143.   
  144.                 bRc = FALSE;  
  145.             }  
  146.             else  
  147.             {  
  148.                 BAK_AdjuctBacklightLevel(*(DWORD*)pBufOut);  
  149.                 // Adjust backlight level.  
  150.                 *(DWORD*)pBufOut = ERROR_SUCCESS;  
  151.                 *pdwActualOut = sizeof(DWORD);  
  152.                 bRc = TRUE;  
  153.             }  
  154.          }  
  155.          else  
  156.          {  
  157.             bRc = FALSE;  
  158.          }  
  159.         break;  
  160.     case IOCTL_BACKLIGHT_GETLEVEL:                
  161.          if (pBufOut != NULL && (dwLenOut>=sizeof(DWORD)))  
  162.          {  
  163.             // Return the current backlight level.  
  164.             *(DWORD*)pBufOut = l_dwBackLightLevel;  
  165.             *pdwActualOut = sizeof(DWORD);  
  166.             bRc = TRUE;  
  167.          }  
  168.          else  
  169.          {  
  170.             bRc = FALSE;  
  171.          }  
  172.         break;    
  173.      }  
  174.     return(bRc);  
  175. }  

 

可以看到有如下几个case:

IOCTL_POWER_CAPABILITIES;

IOCTL_POWER_QUERY;

IOCTL_POWER_SET;

IOCTL_POWER_GET;

IOCTL_BACKLIGHT_ADJUST;

IOCTL_BACKLIGHT_GETLEVEL;

其中

IOCTL_POWER_CAPABILITIES:代表电源管理器请求设备驱动返回设备支持的电源状态及相关特征;

IOCTL_POWER_SET:请求驱动更新设备的电源状态;
IOCTL_POWER_QUERY:电源管理器询问设备是否准备好进行状态切换;
IOCTL_POWER_GET:请求驱动返回当前设备的电源状态;

IOCTL_BACKLIGHT_ADJUST:调节背光亮度的接口;

IOCTL_BACKLIGHT_GETLEVEL:获取背光亮度级别的接口。

0 0