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 + -
显示快捷键?