serialhw.c

来自「Microsoft WinCE 6.0 BSP FINAL release so」· C语言 代码 · 共 1,841 行 · 第 1/5 页

C
1,841
字号
        else {
            if (IsAPIReady(SH_WMGR)) 
                CeEventHasOccurred (NOTIFICATION_EVENT_IR_DISCOVERED,NULL);
        }           
    }
    else {
        EnterCriticalSection(&(pHWHead->RegCritSec));
        try {
            if (pHWHead->sUSR1 & CSP_BITFVAL(UART_USR1_RTSS, UART_USR1_RTSS_SET)) {
                // 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->bDSR) {
                    DEBUGMSG(ZONE_FUNCTION,(TEXT("PutBytes, flowed on via DSR\n")));
                    pHWHead->DSRFlowOff = FALSE;
                    // DSR is set, so go ahead and resume sending
                    // Enable xmit intr.
                    INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_TCEN, UART_UCR4_TCEN_ENABLE);
                    // Then simulate a TX intr to get things moving
                    pHWHead->AddTXIntr = TRUE;
                }
                if (pHWHead->CTSFlowOff && (pHWHead->sUSR1 & CSP_BITFVAL(UART_USR1_RTSS, UART_USR1_RTSS_SET))) {
                    pHWHead->CTSFlowOff = FALSE;
                    // CTS is set, so go ahead and resume sending
                    // Enable xmit intr.
                    INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_TCEN, UART_UCR4_TCEN_ENABLE);
                    // Then simulate a TX intr to get things moving
                    pHWHead->AddTXIntr = TRUE;
                    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_ModemIntrHandler - CTSFlowOff FALSE 0x%x\r\n"),pHWHead->pUartReg->USR1));                
                }
            }
            else{
                DEBUGMSG(ZONE_FUNCTION, (TEXT("RS232 disconnect notification!!!\r\n")));
                EvaluateEventFlag(pHWHead->pMDDContext, EV_RLSD);
            }
        }
        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        }
        LeaveCriticalSection(&(pHWHead->RegCritSec));
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_ModemIntrHandler-\r\n")));

    return;
}


//-----------------------------------------------------------------------------
//
// Function: SL_LineIntrHandler
//
// This function handles the line interrupt. It
// collects the line status of the serial port, and 
// updates internal driver status information.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID SL_LineIntrHandler( PVOID pContext )
{
    DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_LineIntrHandler+ \r\n")));

    SL_ReadLineStatus( pContext );

    DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_LineIntrHandler- \r\n")));

    return;
}


//-----------------------------------------------------------------------------
//
// Function: SL_GetRxBufferSize
//
// This function returns the maximum number of
// bytes that the hardware buffer can hold, not 
// counting the padding, stop, and start bits.
// It would be used only for devices which share a 
// buffer between the MDD/PDD and an ISR.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//
// Returns:  
//      Returns the number of bytes in the hardware receive queue.
//
//-----------------------------------------------------------------------------
ULONG SL_GetRxBufferSize( PVOID pContext )
{
    return(0); //This routine always returns 0 for 16550 UARTS.
}


//-----------------------------------------------------------------------------
//
// Function: SL_ClearDTR
//
// This routine clears DTR.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID SL_ClearDTR( PVOID   pContext )
{

#ifdef DSR_ENABLE

	UartPort Port;
  	UINT16 *pPBC_UartCtrlClear = NULL;	
	PHYSICAL_ADDRESS phyAddr;

	phyAddr.QuadPart = BSP_BASE_REG_PA_PBC_BASE + PBC_UART_CTRL_CLEAR_OFFSET;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_ClearDTR+\r\n")));

	pPBC_UartCtrlClear = (UINT16*) MmMapIoSpace(phyAddr, sizeof(UINT16), FALSE); 

	if(pPBC_UartCtrlSet)
	{	

		EnterCriticalSection(&(pHWHead->RegCritSec));
		try {
			//Clear DTR(DSR) 	
			if(BSPUartGetPort(pHWHead->HwAddr, &Port))
			{
				switch(Port)
				{
					case UARTA:
						// Clear DSR
						OUTREG16(pPBC_UartCtrlClear, (1 << PBC_UART_CTRL_CLEAR_DCE_DSR_LSH));
						break;
					
					case UARTB:
						//Clear DTR
						OUTREG16(pPBC_UartCtrlClear,  (1 << PBC_UART_CTRL_CLEAR_DTE_DTR_LSH));
						break;

					default:
						break;
				}
			}
		}
		except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
			EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
		}

		MmUnmapIoSpace(pPBC_UartCtrlClear, sizeof(UINT16));

		LeaveCriticalSection(&(pHWHead->RegCritSec));
	}
    
	DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_ClearDTR-\r\n")));

#endif

    return;
}


//-----------------------------------------------------------------------------
//
// Function: SL_SetDTR
//
// This routine sets DTR.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID SL_SetDTR( PVOID pContext )
{    

#ifdef DSR_ENABLE

    PUART_INFO pHWHead = (PUART_INFO)pContext;
	UartPort Port;
  	UINT16 *pPBC_UartCtrlSet = NULL;

	PHYSICAL_ADDRESS phyAddrSet,phyAddrClear;
	phyAddrSet.QuadPart = BSP_BASE_REG_PA_PBC_BASE + PBC_UART_CTRL_SET_OFFSET;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_SetDTR+\r\n")));

	pPBC_UartCtrlSet = (UINT16*) MmMapIoSpace(phyAddrSet, sizeof(UINT16), FALSE); // mx27 : Map PBC

	if(pPBC_UartCtrlSet)
	{	

		EnterCriticalSection(&(pHWHead->RegCritSec));
		try {

			if(BSPUartGetPort(pHWHead->HwAddr, &Port))	// mx27 : changed
			{
				switch(Port)
				{
					case UARTA:
						// Set DSR
						OUTREG16(pPBC_UartCtrlSet, (1 << PBC_UART_CTRL_SET_DCE_DSR_LSH));
						break;
						
					case UARTB:
						//Set DTR
						OUTREG16(pPBC_UartCtrlSet,  (1 << PBC_UART_CTRL_SET_DTE_DTR_LSH));
						break;
						
					default:
						break;
				}
			}
		}
		except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
			EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
		}

		MmUnmapIoSpace(pPBC_UartCtrlSet, sizeof(UINT16)); // mx27 : Map PBC

		LeaveCriticalSection(&(pHWHead->RegCritSec));
	}

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_SetDTR-\r\n")));

#endif


    return;
}


//-----------------------------------------------------------------------------
//
// Function: SL_ClearRTS
//
// This routine clears RTS.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID SL_ClearRTS( PVOID pContext )
{
    PUART_INFO pHWHead = (PUART_INFO)pContext;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_ClearRTS+\r\n")));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        //Clear RTS(CTS) to logic "0":high;
        OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_CTS) );

        // If RTS hardware handshaking is enabled and the MDD is 
        // requesting that we flow off, we override the RTS setting
        // controlled by the receiver to avoid overflowing the RX buffer
        if (pHWHead->dcb.fRtsControl == RTS_CONTROL_HANDSHAKE)
        {                
            // set RTS (CTS in MX1) to be controlled by MDD software
            INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_CTSC, UART_UCR2_CTSC_BITCTRL);
        }
        
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
        EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        DEBUGMSG(ZONE_FUNCTION, (TEXT("ClearRTS Not OK\r\n")));        
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-SL_ClearRTS-\r\n")));

    return;
}


//-----------------------------------------------------------------------------
//
// Function: SL_SetRTS
//
// This routine sets RTS.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID SL_SetRTS( PVOID pContext )
{
    PUART_INFO pHWHead = (PUART_INFO)pContext;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_SetRTS+\r\n")));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        // If RTS hardware handshaking is enabled and the MDD is 
        // requesting that we flow on, we give control of the RTS setting
        // back to the the receiver to avoid overflowing the RX FIFO
        if (pHWHead->dcb.fRtsControl == RTS_CONTROL_HANDSHAKE)
        {                
            // set RTS (CTS in MX1) to be controlled by receiver
            INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_CTSC, UART_UCR2_CTSC_RXCTRL);
        }
        
        //Set RTS(CTS) to logic "1":low;
        INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_CTS, UART_UCR2_CTS_LOW);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
        EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_SetRTS-\r\n")));

    return;
}


//-----------------------------------------------------------------------------
//
// Function: SL_ClearBreak
//
// This routine clears break.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID SL_ClearBreak( PVOID pContext )
{
    PUART_INFO pHWHead = (PUART_INFO)pContext;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_ClearBreak+\r\n")));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        //Do not Send Break;
        OUTREG32( &pHWHead->pUartReg->UCR1, INREG32(&pHWHead->pUartReg->UCR1)&~CSP_BITFMASK(UART_UCR1_SNDBRK) );
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
        EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    }
    LeaveCriticalSec

⌨️ 快捷键说明

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