ucbreg.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:6k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. #pragma optimize("", off)
  2. /*++
  3. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  4. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  5. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  6. PARTICULAR PURPOSE.
  7. Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
  8. Module Name:  
  9.   ucbreg.c
  10. Abstract:  
  11.   This module contains routines for manipulating the touch/audio board
  12.   registers.  The FPGA uses a serial interface to actually communicate
  13.   with the board, and indicates completions either by an interrupt, or
  14.   a polled bit.  
  15.   
  16. Functions:
  17.   TchAudAndReg
  18.   TchAudOrReg
  19.   TchAudWriteReg
  20.   TchAudReadReg
  21.   
  22. Notes:
  23. Revision History:
  24.   Glenn Davis 4/1/97
  25. --*/
  26. #include <windows.h>
  27. #include <p2.h>
  28. #include <p2debug.h>
  29. #include <tchaud.h>
  30. #include <drv_glob.h>
  31. /*
  32.  * Timeout value for poll loop waiting for completion of register operation.
  33.  */
  34. #define TCHAUD_REG_TIMEOUT 500 /* ms */
  35. #define TCHAUD_SEM_TIMEOUT  (TCHAUD_REG_TIMEOUT*2)
  36. /*
  37.  * Macro to handle wrap when comparing timestamps
  38.  */
  39. #define ELAPSED_TICKS(start,end)  (((start) <= (end))? ((end) - (start)) : (0xffffffff - (start) + (end) + 1))
  40. /*
  41.  * Routines to provide synchronization for accessing the touch/audio asic
  42.  * registers.  We use a mutex to prevent contention between the touch and
  43.  * audio drivers, and a flag in driver globals to prevent contention with
  44.  * the touch ISR.  If the touch ISR sees the flag set, it will not attempt
  45.  * to access the UCB registers (it will wait until the 5ms pen timer goes off
  46.  * and try again).
  47.  */
  48. void
  49. TchAudLock(HANDLE hMutex, PULONG pSem)
  50. {
  51.     DWORD StartTime = GetTickCount(), CurTime;
  52.     
  53.     WaitForSingleObject(hMutex, TCHAUD_SEM_TIMEOUT);
  54.     // Now, synchronize with ISR. Busy wait OK, since ISR will always preeempt.
  55.     while (InterlockedTestExchange(pSem, 0, 1) != 0) {
  56.         Sleep(0);   // Force reschedule
  57.         CurTime = GetTickCount();
  58.         if (ELAPSED_TICKS(StartTime,CurTime) > TCHAUD_SEM_TIMEOUT) {
  59.             RETAILMSG(1,(TEXT("!TchAudLock: Timed out waiting for semaphore!!!rn")));
  60.             break;
  61.         }
  62.     }
  63. }
  64. void
  65. TchAudUnlock(HANDLE hMutex, PULONG pSem)
  66. {
  67.     *pSem = 0;
  68.     ReleaseMutex(hMutex);
  69. }
  70. /*
  71.  * Routines for accessing the Touch/audio ASIC registers.  To read or write
  72.  * one of the ASIC registers, first specify the register and operation,
  73.  * and then wait for completion, which is indicated by the regIntr bit in the
  74.  * ucbStr register.  We poll for this event in WaitForRegCompletion.
  75.  */
  76. static BOOL 
  77. WaitForRegCompletion(
  78.     volatile PTCHAUD_ASIC_REGISTERS pTchAudRegs,
  79.     BOOL bInPowerHandler)
  80. {
  81.    DWORD StartTime;
  82.    if (!bInPowerHandler)
  83.        StartTime = GetTickCount();
  84.    
  85.    while (1)
  86.    {
  87.        if (pTchAudRegs->ucbStr & intrMaskRegIntrMask) {
  88.            // Clear regIntr interrupt.
  89.            pTchAudRegs->ucbStr = intrMaskRegIntrMask;           
  90.            return TRUE;
  91.        }
  92.        if (!bInPowerHandler) {
  93.            DWORD CurTime = GetTickCount();
  94.            if (ELAPSED_TICKS(StartTime,CurTime) > TCHAUD_REG_TIMEOUT) {
  95.                RETAILMSG(1,(TEXT("!TchAud: Timed out waiting for UCB reg completionnr")));
  96.                return FALSE;
  97.            }
  98.        }
  99.    }
  100.    return FALSE;
  101. }
  102. typedef enum {OP_READ, OP_WRITE,OP_AND,OP_OR} REGOP;
  103. /*
  104.  * Routine to perform read write and modify operations on ASIC registers.
  105.  */
  106. static BOOL
  107. TchAudRegOp(
  108.     USHORT Reg,       // UCB register number
  109.     USHORT Val,       // Value for modify operations
  110.     USHORT *pRetval,  // for OP_READ only 
  111.     REGOP op,         
  112.     volatile PTCHAUD_ASIC_REGISTERS pTchAudRegs,
  113.     BOOL bInPowerHandler)
  114. {
  115.  
  116.     BOOL bRet; 
  117.     USHORT TchAudIntrMask;
  118.     // Make sure regIntr is masked so we don't generate interrupts 
  119.     // when we write to the ASIC.
  120.     TchAudIntrMask = pTchAudRegs->intrMask;
  121.     pTchAudRegs->intrMask = (USHORT)(TchAudIntrMask & ~intrMaskRegIntrMask); 
  122.     // Clear regIntr interrupt just as a precaution.
  123.     pTchAudRegs->ucbStr = intrMaskRegIntrMask;
  124.     if (op != OP_WRITE) {
  125.         // Read register
  126.         pTchAudRegs->ucbCntr = (USHORT)(Reg & ~ucbCntrWriteBit);
  127.         pTchAudRegs->ucbRegister = 0;
  128.         if (WaitForRegCompletion(pTchAudRegs, bInPowerHandler) == FALSE) {
  129.             bRet = FALSE;
  130.             goto RegOpsDone;
  131.         }
  132.         if (op == OP_READ) {
  133.             *pRetval = pTchAudRegs->ucbRegister;
  134.             bRet = TRUE;
  135.             goto RegOpsDone;
  136.         }
  137.         
  138.         if (op == OP_AND)
  139.             Val &= pTchAudRegs->ucbRegister;
  140.         else // OR
  141.             Val |= pTchAudRegs->ucbRegister;
  142.     }
  143.     
  144.     // Write to register
  145. //    RETAILMSG(1,(TEXT("TchAudRegOp: Writing val 0x%X to reg %u, thread: 0x%Xrn"),Val,Reg,GetCurrentThread()));
  146.     pTchAudRegs->ucbCntr     = (USHORT)(Reg | ucbCntrWriteBit);
  147.     pTchAudRegs->ucbRegister = Val;
  148.     bRet = WaitForRegCompletion(pTchAudRegs, bInPowerHandler);
  149. RegOpsDone:
  150.     
  151.     //
  152.     // Restore intrMask register to original value.
  153.     //
  154.     pTchAudRegs->intrMask = TchAudIntrMask;
  155.     return bRet;   
  156. }
  157. BOOL
  158. TchAudReadReg(
  159.     USHORT Reg,
  160.     USHORT *pVal,
  161.     PTCHAUD_ASIC_REGISTERS pTchAudRegs,
  162.     BOOL bInPowerHandler)
  163. {
  164.     return TchAudRegOp(Reg,0,pVal,OP_READ, pTchAudRegs, bInPowerHandler);
  165. }
  166. BOOL
  167. TchAudWriteReg(
  168.     USHORT Reg,
  169.     USHORT Val,
  170.     PTCHAUD_ASIC_REGISTERS pTchAudRegs,
  171.     BOOL bInPowerHandler)
  172. {
  173.     return TchAudRegOp(Reg,Val,NULL,OP_WRITE, pTchAudRegs, bInPowerHandler);
  174. }
  175. BOOL
  176. TchAudAndReg(
  177.     USHORT Reg,
  178.     USHORT Val,
  179.     PTCHAUD_ASIC_REGISTERS pTchAudRegs,
  180.     BOOL bInPowerHandler)
  181. {
  182.     return TchAudRegOp(Reg,Val,NULL,OP_AND, pTchAudRegs, bInPowerHandler);
  183. }
  184. BOOL
  185. TchAudOrReg(
  186.     USHORT Reg,
  187.     USHORT Val,
  188.     PTCHAUD_ASIC_REGISTERS pTchAudRegs,
  189.     BOOL bInPowerHandler)
  190. {
  191.     return TchAudRegOp(Reg,Val,NULL,OP_OR, pTchAudRegs, bInPowerHandler);
  192. }