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