ucbreg.c
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:6k
源码类别:
Windows CE
开发平台:
Windows_Unix
- #pragma optimize("", off)
- /*++
- 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.
- Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
- Module Name:
- ucbreg.c
- Abstract:
- This module contains routines for manipulating the touch/audio board
- registers. The FPGA uses a serial interface to actually communicate
- with the board, and indicates completions either by an interrupt, or
- a polled bit.
- Functions:
- TchAudAndReg
- TchAudOrReg
- TchAudWriteReg
- TchAudReadReg
- Notes:
- Revision History:
- Glenn Davis 4/1/97
- --*/
- #include <windows.h>
- #include <p2.h>
- #include <p2debug.h>
- #include <tchaud.h>
- #include <drv_glob.h>
- /*
- * Timeout value for poll loop waiting for completion of register operation.
- */
- #define TCHAUD_REG_TIMEOUT 500 /* ms */
- #define TCHAUD_SEM_TIMEOUT (TCHAUD_REG_TIMEOUT*2)
- /*
- * Macro to handle wrap when comparing timestamps
- */
- #define ELAPSED_TICKS(start,end) (((start) <= (end))? ((end) - (start)) : (0xffffffff - (start) + (end) + 1))
- /*
- * Routines to provide synchronization for accessing the touch/audio asic
- * registers. We use a mutex to prevent contention between the touch and
- * audio drivers, and a flag in driver globals to prevent contention with
- * the touch ISR. If the touch ISR sees the flag set, it will not attempt
- * to access the UCB registers (it will wait until the 5ms pen timer goes off
- * and try again).
- */
- void
- TchAudLock(HANDLE hMutex, PULONG pSem)
- {
- DWORD StartTime = GetTickCount(), CurTime;
- WaitForSingleObject(hMutex, TCHAUD_SEM_TIMEOUT);
- // Now, synchronize with ISR. Busy wait OK, since ISR will always preeempt.
- while (InterlockedTestExchange(pSem, 0, 1) != 0) {
- Sleep(0); // Force reschedule
- CurTime = GetTickCount();
- if (ELAPSED_TICKS(StartTime,CurTime) > TCHAUD_SEM_TIMEOUT) {
- RETAILMSG(1,(TEXT("!TchAudLock: Timed out waiting for semaphore!!!rn")));
- break;
- }
- }
- }
- void
- TchAudUnlock(HANDLE hMutex, PULONG pSem)
- {
- *pSem = 0;
- ReleaseMutex(hMutex);
- }
- /*
- * Routines for accessing the Touch/audio ASIC registers. To read or write
- * one of the ASIC registers, first specify the register and operation,
- * and then wait for completion, which is indicated by the regIntr bit in the
- * ucbStr register. We poll for this event in WaitForRegCompletion.
- */
- static BOOL
- WaitForRegCompletion(
- volatile PTCHAUD_ASIC_REGISTERS pTchAudRegs,
- BOOL bInPowerHandler)
- {
- DWORD StartTime;
- if (!bInPowerHandler)
- StartTime = GetTickCount();
- while (1)
- {
- if (pTchAudRegs->ucbStr & intrMaskRegIntrMask) {
- // Clear regIntr interrupt.
- pTchAudRegs->ucbStr = intrMaskRegIntrMask;
- return TRUE;
- }
- if (!bInPowerHandler) {
- DWORD CurTime = GetTickCount();
- if (ELAPSED_TICKS(StartTime,CurTime) > TCHAUD_REG_TIMEOUT) {
- RETAILMSG(1,(TEXT("!TchAud: Timed out waiting for UCB reg completionnr")));
- return FALSE;
- }
- }
- }
- return FALSE;
- }
- typedef enum {OP_READ, OP_WRITE,OP_AND,OP_OR} REGOP;
- /*
- * Routine to perform read write and modify operations on ASIC registers.
- */
- static BOOL
- TchAudRegOp(
- USHORT Reg, // UCB register number
- USHORT Val, // Value for modify operations
- USHORT *pRetval, // for OP_READ only
- REGOP op,
- volatile PTCHAUD_ASIC_REGISTERS pTchAudRegs,
- BOOL bInPowerHandler)
- {
- BOOL bRet;
- USHORT TchAudIntrMask;
- // Make sure regIntr is masked so we don't generate interrupts
- // when we write to the ASIC.
- TchAudIntrMask = pTchAudRegs->intrMask;
- pTchAudRegs->intrMask = (USHORT)(TchAudIntrMask & ~intrMaskRegIntrMask);
- // Clear regIntr interrupt just as a precaution.
- pTchAudRegs->ucbStr = intrMaskRegIntrMask;
- if (op != OP_WRITE) {
- // Read register
- pTchAudRegs->ucbCntr = (USHORT)(Reg & ~ucbCntrWriteBit);
- pTchAudRegs->ucbRegister = 0;
- if (WaitForRegCompletion(pTchAudRegs, bInPowerHandler) == FALSE) {
- bRet = FALSE;
- goto RegOpsDone;
- }
- if (op == OP_READ) {
- *pRetval = pTchAudRegs->ucbRegister;
- bRet = TRUE;
- goto RegOpsDone;
- }
- if (op == OP_AND)
- Val &= pTchAudRegs->ucbRegister;
- else // OR
- Val |= pTchAudRegs->ucbRegister;
- }
- // Write to register
- // RETAILMSG(1,(TEXT("TchAudRegOp: Writing val 0x%X to reg %u, thread: 0x%Xrn"),Val,Reg,GetCurrentThread()));
- pTchAudRegs->ucbCntr = (USHORT)(Reg | ucbCntrWriteBit);
- pTchAudRegs->ucbRegister = Val;
- bRet = WaitForRegCompletion(pTchAudRegs, bInPowerHandler);
- RegOpsDone:
- //
- // Restore intrMask register to original value.
- //
- pTchAudRegs->intrMask = TchAudIntrMask;
- return bRet;
- }
- BOOL
- TchAudReadReg(
- USHORT Reg,
- USHORT *pVal,
- PTCHAUD_ASIC_REGISTERS pTchAudRegs,
- BOOL bInPowerHandler)
- {
- return TchAudRegOp(Reg,0,pVal,OP_READ, pTchAudRegs, bInPowerHandler);
- }
- BOOL
- TchAudWriteReg(
- USHORT Reg,
- USHORT Val,
- PTCHAUD_ASIC_REGISTERS pTchAudRegs,
- BOOL bInPowerHandler)
- {
- return TchAudRegOp(Reg,Val,NULL,OP_WRITE, pTchAudRegs, bInPowerHandler);
- }
- BOOL
- TchAudAndReg(
- USHORT Reg,
- USHORT Val,
- PTCHAUD_ASIC_REGISTERS pTchAudRegs,
- BOOL bInPowerHandler)
- {
- return TchAudRegOp(Reg,Val,NULL,OP_AND, pTchAudRegs, bInPowerHandler);
- }
- BOOL
- TchAudOrReg(
- USHORT Reg,
- USHORT Val,
- PTCHAUD_ASIC_REGISTERS pTchAudRegs,
- BOOL bInPowerHandler)
- {
- return TchAudRegOp(Reg,Val,NULL,OP_OR, pTchAudRegs, bInPowerHandler);
- }