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

📄 ser16552.c.bak

📁 2440 wince uart source code
💻 BAK
📖 第 1 页 / 共 4 页
字号:
    RETAILMSG(QYDEBUG,
              (TEXT("+SL_GetModemStatus 0x%X\r\n"), pHead));

    ReadMSRq( pHWHead );
    ubModemStatus = pHWHead->MSR;

    if ( ubModemStatus & SERIAL_MSR_CTS )
        *pModemStatus |= MS_CTS_ON;

    if ( ubModemStatus & SERIAL_MSR_DSR )
        *pModemStatus |= MS_DSR_ON;

    if ( ubModemStatus & SERIAL_MSR_RI )
        *pModemStatus |= MS_RING_ON;

    if ( ubModemStatus & SERIAL_MSR_DCD )
        *pModemStatus |= MS_RLSD_ON;

    DEBUGMSG (ZONE_FUNCTION | ZONE_EVENTS,
              (TEXT("-SL_GetModemStatus 0x%X (stat x%X) \r\n"), pHead, *pModemStatus));
RETAILMSG(QYDEBUG,(TEXT("SL_GetModemStatusq end\r\n")));
    return;
}

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

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_OtherIntr 0x%X\r\n"), pHead));
//RETAILMSG(QYDEBUG,(TEXT("SL_OtherIntrq start\r\n")));
    ReadMSRq( pHWHead );

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        // If we are currently flowed off via CTS or DSR, then
        // we better signal the TX thread when one of them changes
        // so that TX can resume sending.
        if ( pHWHead->DSRFlowOff && (pHWHead->MSR & SERIAL_MSR_DSR) ) {
            DEBUGMSG (ZONE_WRITE|ZONE_FLOW,
                      (TEXT("PutBytes, flowed on via DSR\n") ) );
            pHWHead->DSRFlowOff = FALSE;
            // DSR is set, so go ahead and resume sending
            OUTB(pHWHead, pIER, IER_NORMAL_INTS | SERIAL_IER_THR); // Enable xmit intr.//0x0f
            RETAILMSG(QYDEBUG,(TEXT("SER16550 Register IER(0x0f) =0X%x\r\n"),INB(pHWHead,pIER)));
            // Then simulate a TX intr to get things moving
            pHWHead->AddTXIntr = TRUE;
        }
        if ( pHWHead->CTSFlowOff && (pHWHead->MSR & SERIAL_MSR_CTS) ) {
            DEBUGMSG (ZONE_WRITE|ZONE_FLOW,
                      (TEXT("PutBytes, flowed on via CTS\n") ) );
            pHWHead->CTSFlowOff = FALSE;
            // CTS is set, so go ahead and resume sending
            OUTB(pHWHead, pIER, IER_NORMAL_INTS | SERIAL_IER_THR); // Enable xmit intr.
            RETAILMSG(QYDEBUG,(TEXT("SER16550 Register IER(0x0f) =0X%x\r\n"),INB(pHWHead,pIER)));
            // Then simulate a TX intr to get things moving
            pHWHead->AddTXIntr = TRUE;
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }

    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

BOOL
SL_SetParityq(
            PVOID   pHead,    // @parm     PVOID returned by HWInit
            ULONG   Parity    // @parm     ULONG parity field from DCB.
            )
{
    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;
    UINT8 lcr;
    BOOL bRet;

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

    bRet = TRUE;

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
     lcr = INB(pHWHead, pLCR);
         RETAILMSG(QYDEBUG,(TEXT("SER16550 Register LCR=0x%x\r\n"),lcr));
        lcr &= ~SERIAL_PARITY_MASK;
         RETAILMSG(QYDEBUG,(TEXT("SERIAL3 PARITY =%d\r\n"),Parity));
        switch ( Parity ) {
        case ODDPARITY:
            lcr |= SERIAL_ODD_PARITY;
            break;

        case EVENPARITY:
            lcr |= SERIAL_EVEN_PARITY;
            break;

        case MARKPARITY:
            lcr |= SERIAL_MARK_PARITY;
            break;

        case SPACEPARITY:
            lcr |= SERIAL_SPACE_PARITY;
            break;

        case NOPARITY:
            lcr |= SERIAL_NONE_PARITY;
            break;
        default:
            bRet = FALSE;
            break;
        }
        if (bRet) {
         OUTB(pHWHead, pLCR, lcr);
            RETAILMSG(QYDEBUG,(TEXT("SER16550 Register LCR=0x%x\r\n"),INB(pHWHead, pLCR)));
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        bRet = FALSE;
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

    return(bRet);
}


BOOL
SL_SetStopBitsq(
              PVOID   pHead,      // @parm     PVOID returned by HWInit
              ULONG   StopBits  // @parm     ULONG StopBits field from DCB.
              )
{
    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;
    UINT8 lcr;
    BOOL bRet;

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

    bRet = TRUE;

    EnterCriticalSection(&(pHWHead->RegCritSec));
    lcr = INB(pHWHead, pLCR);
    RETAILMSG(QYDEBUG,(TEXT("SERIAL3 Register LCR=0x%x \r\n"),lcr));
    lcr &= ~SERIAL_STOP_MASK;
 	RETAILMSG(QYDEBUG,(TEXT("SERIAL3 STOP BIT =%d\r\n"),StopBits));
    try {
        // Note that 1.5 stop bits only works if the word size
        // is 5 bits.  Any other xmit word size will cause the
        // 1.5 stop bit setting to generate 2 stop bits.
        switch ( StopBits ) {
        case ONESTOPBIT :
            lcr |= SERIAL_1_STOP ;
            break;
        case ONE5STOPBITS :
            lcr |= SERIAL_1_5_STOP ;
            break;
        case TWOSTOPBITS :
            lcr |= SERIAL_2_STOP ;
            break;
        default:
            bRet = FALSE;
            break;
        }

        if (bRet) {
         OUTB(pHWHead, pLCR, lcr);
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        bRet = FALSE;
    }

    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

    return(bRet);
}

ULONG
SL_GetRxBufferSizeq(
                  PVOID pHead
                  )
{
	RETAILMSG(QYDEBUG,(TEXT("SL_GetRufferSizeq() \r\n")));
    return(0);
}

PVOID
SL_GetRxStartq(
             PVOID   pHead // @parm PVOID returned by SC_init.
             )
{
RETAILMSG(QYDEBUG,(TEXT("SL_GetRxStartq\r\n")));
    return(NULL);
}


INTERRUPT_TYPE
SL_GetInterruptTypeq(
                   PVOID pHead      // Pointer to hardware head
                   )
{
    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;
    INTERRUPT_TYPE interrupts=INTR_NONE;
    RETAILMSG(0,
              (TEXT("+SL_GetInterruptType 0x%X\r\n"), pHead));

    try {
        pHWHead->IIR = INB(pHWHead, pIIR_FCR);

    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        pHWHead->IIR = SERIAL_IIR_INT_INVALID; // simulate no interrupt
    }

    if ( pHWHead->IIR & SERIAL_IIR_INT_INVALID ) {
        // No interrupts pending, vector is useless
        interrupts = INTR_NONE;//interrupt ID =0
    } else {
        // The interrupt value is valid
        switch ( pHWHead->IIR & SERIAL_IIR_INT_MASK ) {
        case SERIAL_IIR_RLS://Receiver Line Status
            interrupts = INTR_LINE;//interrupt ID=1
            break;

        case SERIAL_IIR_CTI://Receiver Date Time Out
        case SERIAL_IIR_CTI_2://(Transmitter Holding Register Empty) &(Receiver Date Time Out)
        case SERIAL_IIR_RDA://Receiver Date Ready
            interrupts = INTR_RX;//interrupt ID =2
 
            break;

        case SERIAL_IIR_THRE ://Transmitter Holding Register Empty
            interrupts = INTR_TX;//interrupt ID =4
            break;

        case SERIAL_IIR_MS ://Modem Status Register
            interrupts = INTR_MODEM;//interrupt ID =8
            break;

        default:
            interrupts = INTR_NONE;//interrupt ID =0
            break;
        }
    }

    if (pHWHead->AddTXIntr) {
        interrupts |= INTR_TX;
        pHWHead->AddTXIntr = FALSE;
    }

   
   	RETAILMSG(0,((TEXT("-SL_GetInterruptTypeq(return(interrupts= 0x%x))\r\n")),interrupts));
	
    return(interrupts);
}


ULONG
SL_RxIntrq(
         PVOID pHead,                // @parm Pointer to hardware head
         PUCHAR pRxBuffer,           // @parm Pointer to receive buffer
         ULONG *pBufflen             // @parm In = max bytes to read, out = bytes read
         )
{
    PSER16550_INFO   pHWHead    = (PSER16550_INFO)pHead;
    ULONG        RetVal    = 0;
    ULONG        TargetRoom    = *pBufflen;
    BOOL        fRXFlag = FALSE;
    BOOL        fReplaceparityErrors = FALSE;
    BOOL        fNull;
    UCHAR       cEvtChar, cRXChar;

    RETAILMSG(QYDEBUG, (TEXT("+SL_RxIntrq() %d.\r\n"),
                  *pBufflen));
     		*pBufflen = 0;

    // LAM - I have local copies of some DCB elements since I don't
    // want to keep dereferencing inside my read loop and there are too
    // many of them to trust the compiler.
    cEvtChar = pHWHead->dcb.EvtChar;
    fNull = pHWHead->dcb.fNull;
    if ( pHWHead->dcb.fErrorChar && pHWHead->dcb.fParity )
        fReplaceparityErrors = TRUE;

    try {
    	
 
    //      while ( TargetRoom ) 
    //****
    		while (INB(pHWHead, pIIR_FCR)&0x06)
        	{

          // See if there is another byte to be read
	//ReadLSRq( pHWHead );
   	 // pHWHead->LSR = INB(pHWHead, pLSR);

 //	if ( pHWHead->LSR & SERIAL_LSR_DR ) {//receive data ready (0x01) 
	//	if ( pHWHead->LSR & 0x15 ) {
 	// Read the byte
                cRXChar = INB(pHWHead, pData);

     //	}else {
                // We read all chars, so we're done
     //         break;
     //   }

        
		RETAILMSG(0,(TEXT("SERIAL3 Receive Char =%c , 0x%x\r\n"),cRXChar));
                // But we may want to discard it
                if ( pHWHead->dcb.fDsrSensitivity &&
                     (! (pHWHead->MSR & SERIAL_MSR_DSR)) ) {
                    // Do nothing - byte gets discarded
               RETAILMSG (QYDEBUG,
                              (TEXT("Dropping byte because DSR is low\r\n")));
                } else if (!cRXChar && fNull) {
                    // Do nothing - byte gets discarded
                    RETAILMSG (QYDEBUG,
                              (TEXT("Dropping NULL byte due to fNull\r\n")));
                } else {
                    // Do character replacement if parity error detected.
                    if ( fReplaceparityErrors && (pHWHead->LSR & SERIAL_LSR_PE) ) {
                        cRXChar = pHWHead->dcb.ErrorChar;
                    } else {
                        // See if we need to generate an EV_RXFLAG for the received char.
                        if ( cRXChar == cEvtChar )
                            fRXFlag = TRUE;
                    }

                    // Finally, we can get byte, update status and save.
                    *pRxBuffer++ = cRXChar;
                    (*pBufflen)++;
                    --TargetRoom;
                }
            } 
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // just exit
    }

    // if we saw one (or more) EVT chars, then generate an event
    if ( fRXFlag )
        pHWHead->EventCallback( pHWHead->pMddHead, EV_RXFLAG );

    if ( pHWHead->DroppedBytes )
        DEBUGMSG (ZONE_WARN, (TEXT("Rx drop %d.\r\n"),
                              pHWHead->DroppedBytes));

    RetVal = pHWHead->DroppedBytes;
    pHWHead->DroppedBytes = 0;
//****
	 OUTB(pHWHead, pIER, 0x01);
  RETAILMSG(QYDEBUG,(TEXT("-SL_Rxtrq() END\r\n")));
    return(RetVal);
}



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

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

    // Disable xmit intr.  Most 16550s will keep hammering
    // us with xmit interrupts if we don't turn them off
    // Whoever gets the FlushDone will then need to turn
    // TX Ints back on if needed.
    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        OUTB(pHWHead, pIER, IER_NORMAL_INTS);
    }
    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));
   
    // Let the putbytes routine know he can continue
    PulseEvent(pHWHead->FlushDone);
   
    RETAILMSG(0,
              (TEXT("-SL_TxIntr 0x%X\r\n"), pHead));
}


//
// @doc OEM
// @func ULONG | SL_TXIntrEx | This routine is called from the new MDD
//   whenever INTR_TX is returned by SL_GetInterruptType
// 
// @rdesc None
//
VOID
SL_TxIntrExq(
           PVOID pHead,                // Hardware Head
           PUCHAR pTxBuffer,          // @parm Pointer to receive buffer
           ULONG *pBufflen            // @parm In = max bytes to transmit, out = bytes transmitted
           )
{
    PSER16550_INFO   pHWHead    = (PSER16550_INFO)pHead;
    ULONG NumberOfBytes = *pBufflen;

    DEBUGMSG (ZONE_THREAD, (TEXT("Transmit Event\r\n")));

    DEBUGMSG (ZONE_WRITE,
              (TEXT("+SL_TxIntrEx 0x%X, Len %d\r\n"), pHead, *pBufflen));
   RETAILMSG (QYDEBUG,
              (TEXT("+SL_TxIntrEx 0x%X, Len %d\r\n"), pHead, *pBufflen));


    // We may be done sending.  If so, just disable the TX interrupts
    // and return to the MDD.  
    if( ! *pBufflen ) {
        DEBUGMSG (ZONE_WRITE, (TEXT("SL_TxIntrEx: Disable INTR_TX.\r\n")));
         RETAILMSG (QYDEBUG, (TEXT("SL_TxIntrEx: Disable INTR_TX.\r\n")));
   
      OUTB(pHWHead, pIER, IER_NORMAL_INTS);
        return;
    }

    *pBufflen = 0;  // In case we don't send anything below.
    
    // Disable xmit intr.  Most 16550s will keep hammering
    // us with xmit interrupts if we don't turn them off
    // Whoever gets the FlushDone will then need to turn
    // TX Ints back on if needed.
    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        // Need to signal FlushDone for XmitComChar
        PulseEvent(pHWHead->FlushDone);

        pHWHead->CommErrors &= ~CE_TXFULL;

        // If CTS flow control is desired, check cts. If clear, don't send,
        // but loop.  When CTS comes back on, the OtherInt routine will
        // detect this and re-enable TX interrupts (causing Flushdone).
        // For finest granularity, we would check this in the loop below,
        // but for speed, I check it here (up to 8 xmit characters before
        // we actually flow off.
        if ( pHWHead->dcb.fOutxCtsFlow ) {
            // 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_CTS) ) {
            	ULONG value;

⌨️ 快捷键说明

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