⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ser16552.c

📁 2440 wince uart source code
💻 C
📖 第 1 页 / 共 5 页
字号:
  //      }
   }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Hmm, not sure what would cause this.  Lets just tell
        // the MDD to go away until we get another TX
        // interrupt.
        RETAILMSG(QYDEBUG,(TEXT("SL_TxIntrEx:except.\r\n")));
    }

    LeaveCriticalSection(&(pHWHead->RegCritSec));

    LeaveCriticalSection(&(pHWHead->TransmitCritSec));
    DEBUGMSG (ZONE_WRITE, (TEXT("SL_TxIntrEx released CritSec %x.\r\n"),
                           &(pHWHead->TransmitCritSec)));

    DEBUGMSG (ZONE_WRITE, (TEXT("-SL_TxIntrEx - sent %d.\r\n"),
                           *pBufflen));
    return;

}


VOID
SL_LineIntrq(
           PVOID pHead                // Hardware Head
           )
{
    PSER16550_INFO   pHWHead    = (PSER16550_INFO)pHead;

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_LineIntr 0x%X\r\n"), pHead));

    ReadLSRq( pHWHead );

    RETAILMSG(QYDEBUG,
              (TEXT("-SL_LineIntr 0x%X\r\n"), pHead));
}

ULONG
SL_GetStatusq(
            PVOID    pHead,    // @parm PVOID returned by HWInit.
            LPCOMSTAT    lpStat    // Pointer to LPCOMMSTAT to hold status.
            )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
    ULONG      RetVal  = pHWHead->CommErrors;

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_GetStatus 0x%X\r\n"), pHead));

    pHWHead->CommErrors = 0; // Clear old errors each time

    if ( lpStat ) {
        try {
            if (pHWHead->CTSFlowOff)
                pHWHead->Status.fCtsHold = 1;
            else
                pHWHead->Status.fCtsHold = 0;

            if (pHWHead->DSRFlowOff)
                pHWHead->Status.fDsrHold = 1;
            else
                pHWHead->Status.fDsrHold = 0;

            // NOTE - I think what they really want to know here is
            // the amount of data in the MDD buffer, not the amount
            // in the UART itself.  Just set to 0 for now since the
            // MDD doesn't take care of this.
            pHWHead->Status.cbInQue  = 0;
            pHWHead->Status.cbOutQue = 0;

            memcpy(lpStat, &(pHWHead->Status), sizeof(COMSTAT));
        }
        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            RetVal = (ULONG)-1;
        }        
    } else
        RetVal = (ULONG)-1;

    RETAILMSG(QYDEBUG,
              (TEXT("-SL_GetStatus 0x%X\r\n"), pHead));
    return(RetVal);
}


VOID
SL_Resetq(
        PVOID   pHead    // @parm PVOID returned by HWInit.
        )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_Reset 0x%X\r\n"), pHead));

    memset(&pHWHead->Status, 0, sizeof(COMSTAT));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        OUTB(pHWHead, pIER, IER_NORMAL_INTS);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Do nothing
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    RETAILMSG(QYDEBUG,
              (TEXT("-SL_Reset 0x%X\r\n"), pHead));
}

VOID
SL_PurgeCommq(
            PVOID   pHead,        // @parm PVOID returned by HWInit.
            DWORD   fdwAction        // @parm Action to take. 
            )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
    RETAILMSG(QYDEBUG,
              (TEXT("+SL_PurgeComm 0x%X\r\n"), pHead));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
#ifdef TODO
        // REVIEW THIS - I don't see how this could have terminated a pending read,
        // nor how RX interrupts would ever get turned back on.  I suspect that
        // RXABORT and TXABORT would both be better implemented in the MDD.
        if ( fdwAction & PURGE_RXABORT )
            OUTB(pHWHead, pIER, IER_NORMAL_INTS & ~SERIAL_IER_RDA);
#endif    
        if ( fdwAction & PURGE_TXCLEAR ) {
            // Write the TX reset bit.  It is self clearing
            OUTB(pHWHead, pIIR_FCR, pHWHead->FCR | SERIAL_FCR_TXMT_RESET);
        }
     
        if ( fdwAction & PURGE_RXCLEAR ) {
            // Write the RX reset bit.  It is self clearing
            OUTB(pHWHead, pIIR_FCR, pHWHead->FCR | SERIAL_FCR_RCVR_RESET);
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }



    LeaveCriticalSection(&(pHWHead->RegCritSec));
 
RETAILMSG(QYDEBUG,(TEXT("LCR  		:0x%x\r\n"),INB(pHWHead, pLCR)));
RETAILMSG(QYDEBUG,(TEXT("IER  		:0x%x\r\n"),INB(pHWHead, pIER)));
	RETAILMSG(QYDEBUG,(TEXT("IIR_FCR  	:0x%x\r\n"),INB(pHWHead, pIIR_FCR)));
	
	RETAILMSG(QYDEBUG,(TEXT("MCR  		:0x%x\r\n"),INB(pHWHead, pMCR)));
	
    RETAILMSG(QYDEBUG,
              (TEXT("-SL_PurgeComm 0x%X\r\n"), pHead));
    return;
}


BOOL
SL_XmitComCharq(
              PVOID   pHead,    // @parm PVOID returned by HWInit.
              UCHAR   ComChar   // @parm Character to transmit. 
              )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_XmitComChar 0x%X\r\n"), pHead));

    // Get critical section, then transmit when buffer empties
    RETAILMSG(QYDEBUG, (TEXT("XmitComChar wait for CritSec %x.\r\n"),
                           &(pHWHead->TransmitCritSec)));
    EnterCriticalSection(&(pHWHead->TransmitCritSec));
    RETAILMSG(QYDEBUG, (TEXT("XmitComChar got CritSec %x.\r\n"),
                           &(pHWHead->TransmitCritSec)));
    try {
        while ( TRUE ) {  // We know THR will eventually empty
            EnterCriticalSection(&(pHWHead->RegCritSec));
            // Write the character if we can
            ReadLSRq( pHWHead );
            if ( pHWHead->LSR & SERIAL_LSR_THRE ) {
                // FIFO is empty, send this character
                OUTB(pHWHead, pData, ComChar);
                // Make sure we release the register critical section
                LeaveCriticalSection(&(pHWHead->RegCritSec));

                RETAILMSG(QYDEBUG, (TEXT("XmitComChar wrote x%X\r\n"),
                                       ComChar));
                break;
            }

            // If we couldn't write the data yet, then wait for a
            // TXINTR to come in and try it again.

            // Enable xmit intr.
            OUTB(pHWHead, pIER, IER_NORMAL_INTS | SERIAL_IER_THR);
            LeaveCriticalSection(&(pHWHead->RegCritSec));

            // Wait until the txintr has signalled.
            RETAILMSG(QYDEBUG, (TEXT("XmitComChar WaitIntr x%X\r\n"),
                                   pHWHead->FlushDone));
            WaitForSingleObject(pHWHead->FlushDone, (ULONG)1000);
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Make sure we release the register critical section
        LeaveCriticalSection(&(pHWHead->RegCritSec));
    }

    LeaveCriticalSection(&(pHWHead->TransmitCritSec));
    RETAILMSG(QYDEBUG, (TEXT("XmitComChar released CritSec %x.\r\n"),
                           &(pHWHead->TransmitCritSec)));

    RETAILMSG(QYDEBUG,
              (TEXT("-SL_XmitComChar 0x%X\r\n"), pHead));

    return(TRUE);
}

VOID
SL_PowerOffq(
           PVOID   pHead        // @parm    PVOID returned by HWInit.
           )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
	RETAILMSG(QYDEBUG,(TEXT("+SL_PowerOffq, 0x%X\r\n"), pHWHead));
    // Current FCR is already saved in a shadow

    // Current IER is not normally shadowed, save it
    pHWHead->IER = INB(pHWHead, pIER);

    // Current LCR is not normally shadowed, save it
    pHWHead->LCR = INB(pHWHead, pLCR);

    // Current MCR is not normally shadowed, save it
    pHWHead->MCR = INB(pHWHead, pMCR);

    // Current Scratch is not normally shadowed, save it
    pHWHead->Scratch = INB(pHWHead, pScratch);
    RETAILMSG(QYDEBUG,(TEXT("-SL_PowerOffq, 0x%X\r\n"), pHWHead));
}

VOID
SL_PowerOnq(
          PVOID   pHead        // @parm    PVOID returned by HWInit.
          )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
	RETAILMSG(QYDEBUG,(TEXT("+SL_PowerOnq, 0x%X\r\n"), pHWHead));
    // Restore any registers that we need

    // In power handler context, so don't try to do a critical section
    OUTB(pHWHead, pIIR_FCR, pHWHead->FCR);
    OUTB(pHWHead, pIER, pHWHead->IER);
    OUTB(pHWHead, pLCR, pHWHead->LCR);
    OUTB(pHWHead, pMCR, pHWHead->MCR);
    OUTB(pHWHead, pScratch, pHWHead->Scratch);
//****
  pHWHead->PowerDown = FALSE;

    // And we didn't save the Divisor Reg, so set baud rate
    // But don't call SL_SetBaud, since it does DebugMsg.
    // Call our internal function instead.  Can't acquire
    // the RegCritSec, but shouldn't really need to since
    // we are in power context.
    SetBaudRateq( pHWHead, pHWHead->dcb.BaudRate );
    RETAILMSG(QYDEBUG,(TEXT("-SL_PowerOnq, 0x%X\r\n"), pHWHead));
}

BOOL
SL_SetDCBq(
         PVOID   pHead,        // @parm    PVOID returned by HWInit.
         LPDCB   lpDCB       // @parm    Pointer to DCB structure
         )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
    BOOL bRet;

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_SetDCB 0x%X\r\n"), pHead));

    bRet = TRUE;

    // If the device is open, scan for changes and do whatever
    // is needed for the changed fields.  if the device isn't
    // open yet, just save the DCB for later use by the open.
    if ( pHWHead->OpenCount ) {
        // Note, fparity just says whether we should check
        // receive parity.  And the 16550 won't let us NOT
        // check parity if we generate it.  So this field
        // has no effect on the hardware.

        if ( lpDCB->BaudRate != pHWHead->dcb.BaudRate ) {
            bRet = SL_SetBaudRateq( pHWHead, lpDCB->BaudRate );
        }

        if ( bRet && (lpDCB->ByteSize != pHWHead->dcb.ByteSize )) {
            bRet = SL_SetByteSizeq( pHWHead, lpDCB->ByteSize );
        }

        if ( bRet && (lpDCB->Parity != pHWHead->dcb.Parity )) {
            bRet = SL_SetParityq( pHWHead, lpDCB->Parity );
        }

        if ( bRet && (lpDCB->StopBits != pHWHead->dcb.StopBits )) {
            bRet = SL_SetStopBitsq( pHWHead, lpDCB->StopBits );
        }

        // Don't worry about fOutxCtsFlow.  It is a flag which
        // will be examined every time we load the TX buffer.
        // No special action required here.
    }

    if (bRet) {
        // Now that we have done the right thing, store this DCB
        pHWHead->dcb = *lpDCB;
    }


    RETAILMSG(QYDEBUG,
              (TEXT("-SL_SetDCB 0x%X\r\n"), pHead));

    return(bRet);
}


ULONG
SL_SetCommTimeoutsq(
                  PVOID   pHead,        // @parm    PVOID returned by HWInit.
                  LPCOMMTIMEOUTS   lpCommTimeouts // @parm Pointer to CommTimeout structure
                  )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
    ULONG retval = 0;

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_SetCommTimeout 0x%X\r\n"), pHead));

    // OK, first check for any changes and act upon them
    if ( lpCommTimeouts->WriteTotalTimeoutMultiplier !=
         pHWHead->CommTimeouts.WriteTotalTimeoutMultiplier ) {
    }

    // Now that we have done the right thing, store this DCB
    pHWHead->CommTimeouts = *lpCommTimeouts;
 //****
 	OUTB(pHWHead, pLCR, 0X03);

    RETAILMSG(QYDEBUG,
              (TEXT("-SL_SetCommTimeout 0x%X\r\n"), pHead));

    return(retval);
}
BOOL
SL_Ioctlq(PVOID pHead, DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,
         PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
    BOOL RetVal = TRUE;
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_Ioctl 0x%X\r\n"), pHead));
    switch (dwCode) {

    // Currently, no defined IOCTLs
    default:
        RetVal = FALSE;
        DEBUGMSG (ZONE_FUNCTION, (TEXT(" Unsupported ioctl 0x%X\r\n"), dwCode));
        break;            
    }
    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_Ioctl 0x%X\r\n"), pHead));
    return(RetVal);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -