serialhw.c
来自「Microsoft WinCE 6.0 BSP FINAL release so」· C语言 代码 · 共 1,841 行 · 第 1/5 页
C
1,841 行
if (pHWHead->UseIrDA) {
BSPIrdaEnable(TRUE);
BSPIrdaSetMode(SIR_MODE);
}
if (! BSPUartConfigGPIO(pHWHead->HwAddr, pHWHead->UseIrDA, TRUE)) {
DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_Open: BSPUartConfigGPIO failed!\r\n")));
return FALSE;
}
OUTREG32(&pHWHead->pUartReg->UCR1, CSP_BITFVAL(UART_UCR1_UARTEN, UART_UCR1_UARTEN_ENABLE) |//Enable UART
CSP_BITFVAL(UART_UCR1_ICD, UART_UCR1_ICD_8FRAMES)); //idle condition detect
OUTREG32(&pHWHead->pUartReg->UCR2, CSP_BITFVAL(UART_UCR2_SRST, UART_UCR2_SRST_NORESET));
OUTREG32(&pHWHead->pUartReg->UCR3, CSP_BITFVAL(UART_UCR3_RXDMUXSEL, UART_UCR3_RXDMUXSEL_MUX));
OUTREG32(&pHWHead->pUartReg->UCR4, CSP_BITFVAL(UART_UCR4_CTSTL, UART_RXFIFO_DEPTH/2));
bDIV = SL_CalculateRFDIV(&bRefFreq);
OUTREG32(&pHWHead->pUartReg->UFCR, CSP_BITFVAL(UART_UFCR_RXTL, SER_FIFO_RXTL) |
CSP_BITFVAL(UART_UFCR_TXTL, SER_FIFO_TXTL) |
CSP_BITFVAL(UART_UFCR_RFDIV, bDIV));
if (pHWHead->UartType == DTE)
OUTREG32(&pHWHead->pUartReg->UFCR, INREG32(&pHWHead->pUartReg->UFCR)|CSP_BITFVAL(UART_UFCR_DCEDTE, UART_UFCR_DCEDTE_DTE)); // Configure as DTE
OUTREG32(&pHWHead->pUartReg->ONEMS, (UINT16)(bRefFreq/1000));
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_INIT3 RTS 0x%x\r\n"), pHWHead->pUartReg->UCR2));
//Clear RTS
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_CTS) );
if (!pHWHead->UseIrDA) {
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_RTSDEN, UART_UCR1_RTSDEN_ENABLE);
} else {
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_ENIRI, UART_UCR4_ENIRI_ENABLE);
}
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_INIT-\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: SL_Deinit
//
// This function frees any memory allocated.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_Deinit( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_Deinit+\r\n")));
OUTREG32( &pHWHead->pUartReg->UCR1, INREG32(&pHWHead->pUartReg->UCR1)&~CSP_BITFMASK(UART_UCR1_UARTEN) ); // Disable UART
// Disable extern IrDa pin
if (pHWHead->UseIrDA) {
BSPIrdaEnable(FALSE);
}
BSPUartEnableClock(pHWHead->HwAddr, FALSE);
BSPUartConfigGPIO(pHWHead->HwAddr, pHWHead->UseIrDA, FALSE);
if (pHWHead->FlushDone) {
CloseHandle(pHWHead->FlushDone);
pHWHead->FlushDone = NULL;
}
// delete the critical section
DeleteCriticalSection(&(pHWHead->TransmitCritSec));
DeleteCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_Deinit-\r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_Open
//
// This function is called by the upper layer to
// open the serial device.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_Open( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
ULONG bRefFreq = UART_REF_FREQ;
UCHAR bDIV = 0;
DEBUGMSG(ZONE_OPEN, (TEXT("SL_Open+ \r\n")));
SL_ClearPendingInts(pHWHead);
pHWHead->DroppedBytes = 0;
pHWHead->CTSFlowOff = FALSE; // Not flowed off yet
pHWHead->DSRFlowOff = FALSE; // Not flowed off yet
pHWHead->CommErrors = 0;
pHWHead->ModemStatus = 0;
//initialize as logic 0:high
pHWHead->bDSR = TRUE;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
DEBUGMSG(ZONE_OPEN, (TEXT("SL_Open Setting DCB parameters\r\n")));
OUTREG32(&pHWHead->pUartReg->UCR1, CSP_BITFVAL(UART_UCR1_UARTEN, UART_UCR1_UARTEN_ENABLE) |//Enable UART
CSP_BITFVAL(UART_UCR1_ICD, UART_UCR1_ICD_8FRAMES)); //idle condition detect
OUTREG32(&pHWHead->pUartReg->UCR2, CSP_BITFVAL(UART_UCR2_SRST, UART_UCR2_SRST_NORESET) | //no reset
CSP_BITFVAL(UART_UCR2_WS, UART_UCR2_WS_8BIT)); //8 Bits
OUTREG32(&pHWHead->pUartReg->UCR3, CSP_BITFVAL(UART_UCR3_RXDMUXSEL, UART_UCR3_RXDMUXSEL_MUX));
OUTREG32(&pHWHead->pUartReg->UCR4, CSP_BITFVAL(UART_UCR4_CTSTL, UART_RXFIFO_DEPTH/2));
bDIV = SL_CalculateRFDIV(&bRefFreq);
OUTREG32(&pHWHead->pUartReg->UFCR, CSP_BITFVAL(UART_UFCR_RXTL, SER_FIFO_RXTL) |
CSP_BITFVAL(UART_UFCR_TXTL, SER_FIFO_TXTL) |
CSP_BITFVAL(UART_UFCR_RFDIV, bDIV));
if (pHWHead->UartType == DTE)
OUTREG32(&pHWHead->pUartReg->UFCR, INREG32(&pHWHead->pUartReg->UFCR)|CSP_BITFVAL(UART_UFCR_DCEDTE, UART_UFCR_DCEDTE_DTE)); // Configure as DTE
OUTREG32(&pHWHead->pUartReg->ONEMS, (UINT16)(bRefFreq/1000));
// Get defaults from the DCB structure
SL_SetByteSize(pContext, pHWHead->dcb.ByteSize);
SL_SetStopBits(pContext, pHWHead->dcb.StopBits);
SL_SetParity(pContext, pHWHead->dcb.Parity);
SL_SetBaudRate(pContext, pHWHead->dcb.BaudRate);
//Enable Transmiter & Receiver
INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_TXEN, UART_UCR2_TXEN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_RXEN, UART_UCR2_RXEN_ENABLE);
//Ignore CTS
OUTREG32(&pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)| CSP_BITFVAL(UART_UCR2_IRTS, UART_UCR2_IRTS_IGNORERTS));
//Set RTS
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_CTSC) );
INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_CTS, UART_UCR2_CTS_LOW);
SL_ClearPendingInts( pHWHead );
//Enable Aging timer interrupt
INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_ATEN, UART_UCR2_ATEN_ENABLE);
//Enable Parity Error Interrupt;
//Enable Frame Error interrupt;
INSREG32BF(&pHWHead->pUartReg->UCR3, UART_UCR3_PARERREN, UART_UCR3_PARERREN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR3, UART_UCR3_FRAERREN, UART_UCR3_FRAERREN_ENABLE);
//Enable Break Condition Detected Interrupt;
//Enable Overrun interrupt;
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_BKEN, UART_UCR4_BKEN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_OREN, UART_UCR4_OREN_ENABLE);
//Enable Receiver Data Ready Interrupt;
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_DREN, UART_UCR4_DREN_ENABLE);
if (pHWHead->UseIrDA) {
//Enable IR interrupt
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_ENIRI, UART_UCR4_ENIRI_ENABLE);
OUTREG32( &pHWHead->pUartReg->UCR1, INREG32(&pHWHead->pUartReg->UCR1)&~CSP_BITFMASK(UART_UCR1_RTSDEN) );
}
else {
//Enable CTS state change Interrupt;
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_RTSDEN, UART_UCR1_RTSDEN_ENABLE);
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG(ZONE_OPEN, (TEXT("SL_Open- \r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_Close
//
// This function closes the device initialized
// by the SL_Init function.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_Close( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
DEBUGMSG(ZONE_CLOSE,(TEXT("SL_Close+ \r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
if (pHWHead->UseIrDA)
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_ENIRI) );
//Disable Receiver Data Ready Interrupt;
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_DREN) );
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_TCEN) );
//Disable Break Condition Detected Interrupt;
//Disable Overrun interrupt;
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_BKEN) );
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_OREN) );
//Disable Parity Error Interrupt;
//Disable Frame Error interrupt;
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_PARERREN) );
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_FRAERREN) );
//Disable Aging timer interrupt
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_ATEN) );
//Clear RTS
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_CTS) );
//Disable Transmiter & Receiver
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_TXEN) );
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_RXEN) );
SL_ClearPendingInts( pHWHead );
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG(ZONE_CLOSE,(TEXT("SL_Close- \r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_PowerOff
//
// This routine performs powerdown sequence.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_PowerOff( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_PowerOff+ \r\n")));
// Disable UART
OUTREG32( &pHWHead->pUartReg->UCR1, INREG32(&pHWHead->pUartReg->UCR1)&~CSP_BITFMASK(UART_UCR1_UARTEN) );
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_PowerOff- \r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_PowerOn
//
// This routine performs poweron sequence.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_PowerOn( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_PowerOn+ \r\n")));
pHWHead->ulDiscard = 0;
// Restore any registers that we need
// In power handler context, so don't try to do a critical section
// Enable UART
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_UARTEN, UART_UCR1_UARTEN_ENABLE);
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_PowerOn- \r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_GetIntrType
//
// This function is called by the MDD whenever
// an interrupt occurs. The return code is then
// checked by the MDD to determine which of the four
// interrupt handling routines are to be called.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// This routine returns a bitmask indicating
// which interrupts are currently pending. It returns
// one of the following interrupt types:
// INTR_NONE
// INTR_LINE
// INTR_RX
// INTR_TX
// INTR_MODEM
// These interrupt types are declared in Serhw.h.
//
//-----------------------------------------------------------------------------
INTERRUPT_TYPE SL_GetIntrType( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
INTERRUPT_TYPE interrupts;
UINT64 intPndVal = 0;
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_GetIntrType+ \r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
if ((pHWHead->pUartReg->USR1 & CSP_BITFVAL(UART_USR1_FRAMERR, UART_USR1_FRAMERR_SET))
|| (pHWHead->pUartReg->USR1 & CSP_BITFVAL(UART_USR1_PARITYERR, UART_USR1_PARITYERR_SET))
|| (pHWHead->pUartReg->USR2 & CSP_BITFVAL(UART_USR2_BRCD, UART_USR2_BRCD_SET))
|| (pHWHead->pUartReg->USR2 & CSP_BITFVAL(UART_USR2_ORE, UART_USR2_ORE_SET))){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?