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

📄 ser16552.c.bak

📁 2440 wince uart source code
💻 BAK
📖 第 1 页 / 共 4 页
字号:
             
                DEBUGMSG (ZONE_WRITE|ZONE_FLOW,
                          (TEXT("SL_TxIntrEx, flowed off via CTS\n") ) );
                pHWHead->CTSFlowOff = TRUE;  // Record flowed off state
            
                // We could return a positive value here, which would
                // cause the MDD to periodically check the flow control
                // status.  However, we don't need to since we know that
                // the DCTS interrupt will cause the MDD to call us, and we
                // will subsequently fake a TX interrupt to the MDD, causing
                // him to call back into PutBytes.
		  value = INB(pHWHead, pIER);
                OUTB(pHWHead, pIER, value & ~SERIAL_IER_THR); // disable TX interrupts while flowed off
                LeaveCriticalSection(&(pHWHead->RegCritSec));
                return;
            }
        }

        // Same thing applies for DSR
        if ( pHWHead->dcb.fOutxDsrFlow ) {
            // ReadMSR( pHWHead );
            // We don't need to explicitly read the MSR, since we always enable
            // IER_MS, which ensures that we will get an interrupt and read
            // the MSR whenever CTS, DSR, TERI, or DCD change.

            if (! (pHWHead->MSR & SERIAL_MSR_DSR) ) {
            	ULONG value;
                DEBUGMSG (ZONE_WRITE|ZONE_FLOW,
                          (TEXT("SL_TxIntrEx, flowed off via DSR\n") ) );
                pHWHead->DSRFlowOff = TRUE;  // Record flowed off state
            	value = INB(pHWHead, pIER);
                    OUTB(pHWHead, pIER, value & ~IER_NORMAL_INTS); // disable TX interrupts while flowed off
 
                // See the comment above above positive return codes.

                LeaveCriticalSection(&(pHWHead->RegCritSec));
                return;
            }
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Do nothing.  The worst case is that this was a fluke,
        // and a TX Intr will come right back at us and we will
        // resume transmission.
    }

    LeaveCriticalSection(&(pHWHead->RegCritSec));


    //  OK, now lets actually transmit some data.
    DEBUGMSG (ZONE_WRITE, (TEXT("SL_TxIntrEx wait for CritSec %x.\r\n"),
                           &(pHWHead->TransmitCritSec)));
    EnterCriticalSection(&(pHWHead->TransmitCritSec));
    DEBUGMSG (ZONE_WRITE, (TEXT("SL_TxIntrEx got CritSec %x.\r\n"),
                           &(pHWHead->TransmitCritSec)));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
  //          ReadLSRq( pHWHead );
   //     if ( pHWHead->LSR & SERIAL_LSR_THRE ) {
   {             UCHAR       byteCount;
               if ( pHWHead->IIR & SERIAL_IIR_FIFOS_ENABLED )
                    byteCount = SERIAL_FIFO_DEPTH;
                else
                   byteCount = 1;
                
                DEBUGMSG (ZONE_WRITE | ZONE_THREAD,
                    (TEXT("SL_TxIntrEx - Write max of %d bytes\r\n"),
                    byteCount));
             RETAILMSG (QYDEBUG,
                    (TEXT("SL_TxIntrEx - Write max of %d bytes\r\n"),
                    byteCount));
               
                for ( *pBufflen=0; NumberOfBytes && byteCount; NumberOfBytes--, byteCount-- ) {
                    OUTB(pHWHead, pData, *pTxBuffer);
                    InterruptDone(pHWHead->dwSysIntr);
                    ++pTxBuffer;
                    (*pBufflen)++;
                }
        
      }
        // Enable xmit intr. We need to do this no matter what, 
        // since the MDD relies on one final interrupt before
        // returning to the application. 
         RETAILMSG(ZONE_WRITE,(TEXT("SL_TxIntrEx:Enable INTR_TX.\r\n")));
        DEBUGMSG (ZONE_WRITE, (TEXT("SL_TxIntrEx: Enable INTR_TX.\r\n")));
       OUTB(pHWHead, pIER, IER_NORMAL_INTS | SERIAL_IER_THR);
 // 		*(volatile PUCHAR)((volatile PUCHAR)pHead+0x1) = (UCHAR)(IER_NORMAL_INTS | SERIAL_IER_THR);
  //      }
   }
    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.
    }

    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 + -