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

📄 serialhw.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        //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) );
		
        if (pHWHead->UartType == DTE)
        {
            OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_DCD) );
			OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_RI) );
		}

		if (((PSER_INFO)pHWHead)->useDMA)
		{

			DDKSdmaStopChan(((PSER_INFO)pHWHead)->SerialDmaChanRx, TRUE);
			DDKSdmaStopChan(((PSER_INFO)pHWHead)->SerialDmaChanTx, TRUE);

			INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_RDMAEN, UART_UCR1_RXDMAEN_DISABLE);
			INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_TDMAEN, UART_UCR1_TXDMAEN_DISABLE);
			BSPSerRestoreDMAReqGpr(((PSER_INFO)pHWHead)->dwIOBase);
		}

        SL_ClearPendingInts( pHWHead );
		OUTREG32(&pHWHead->pUartReg->UCR1, CSP_BITFVAL(UART_UCR1_UARTEN, UART_UCR1_UARTEN_DISABLE));
    }
    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;
	PSER_INFO pSerHead = (PSER_INFO)pContext;
    INTERRUPT_TYPE interrupts = INTR_NONE;
    UINT64 intPndVal = 0;
	UINT32 rxStatus = 0, txStatus = 0;
	int i;

    DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_GetIntrType+ \r\n")));
    if (pSerHead->useDMA)
	{

		DDKSdmaGetBufDescStatus(pSerHead->SerialDmaChanRx, 0, &rxStatus);
		DEBUGMSG(ZONE_FLOW, (TEXT("DMA rx Buf %d status = 0x%08X\r\n"), 0, rxStatus));

		DDKSdmaGetBufDescStatus(pSerHead->SerialDmaChanRx, 1, &rxStatus);
		DEBUGMSG(ZONE_FLOW, (TEXT("DMA rx Buf %d status = 0x%08X\r\n"), 1, rxStatus));

		DDKSdmaGetBufDescStatus(pSerHead->SerialDmaChanTx, 0, &txStatus);
		DEBUGMSG(ZONE_FLOW, (TEXT("DMA tx Buf 0 status = 0x%08X\r\n"), txStatus));

		DDKSdmaGetBufDescStatus(pSerHead->SerialDmaChanRx, pSerHead->currRxDmaBufId, &rxStatus);
	}
    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))){
            interrupts = INTR_LINE;    // 0x1
        }
        else if ((pHWHead->pUartReg->USR2 & CSP_BITFVAL(UART_USR2_TXDC,UART_USR2_TXDC_SET)) 
            && (pHWHead->pUartReg->UCR4 & CSP_BITFVAL(UART_UCR4_TCEN, UART_UCR4_TCEN_ENABLE))){
            CSP_BITFCLR(pHWHead->pUartReg->UCR4, UART_UCR4_TCEN);
            interrupts = INTR_TX;      // 0x4
        }
        else if (((pHWHead->pUartReg->USR2 & CSP_BITFVAL(UART_USR2_RDR, UART_USR2_RDR_SET))
            && (pHWHead->pUartReg->UCR4 & CSP_BITFVAL(UART_UCR4_DREN, UART_UCR4_DREN_ENABLE)))
            || (pHWHead->pUartReg->USR1 & CSP_BITFVAL(UART_USR1_AGTIM, UART_USR1_AGTIM_SET))){
            OUTREG32(&pHWHead->pUartReg->USR1, CSP_BITFVAL(UART_USR1_AGTIM, UART_USR1_AGTIM_SET)); 
            interrupts = INTR_RX;
        }
        else if (((pHWHead->pUartReg->USR1 & CSP_BITFVAL(UART_USR1_DTRD, UART_USR1_DTRD_SET)) 
            && (pHWHead->pUartReg->UCR3 &  CSP_BITFVAL(UART_UCR3_DTRDEN, UART_UCR3_DTRDEN_ENABLE)))
            || ((pHWHead->pUartReg->USR1 & CSP_BITFVAL(UART_USR1_RTSD, UART_USR1_RTSD_SET)) 
            && (pHWHead->pUartReg->UCR1& CSP_BITFVAL(UART_UCR1_RTSDEN, UART_UCR1_RTSDEN_ENABLE)))
            || ((pHWHead->pUartReg->USR2 & CSP_BITFVAL(UART_USR2_DCDDELT, UART_USR2_DCDDELT_SET)) 
            && (pHWHead->pUartReg->UCR3 & CSP_BITFVAL(UART_UCR3_DCD, UART_UCR3_DCD_ENABLE)))
            || ((pHWHead->pUartReg->USR2 & CSP_BITFVAL(UART_USR2_RIDELT, UART_USR2_RIDELT_SET))) 
            && (pHWHead->pUartReg->UCR3 & CSP_BITFVAL(UART_UCR3_RI, UART_UCR3_RI_ENABLE))){
            interrupts = INTR_MODEM;   // 0x8
        }
        else if (pHWHead->pUartReg->USR2 & CSP_BITFVAL(UART_USR2_IRINT, UART_USR2_IRINT_SET)){    //Infrared
            OUTREG32(&pHWHead->pUartReg->USR2, CSP_BITFVAL(UART_USR2_IRINT, UART_USR2_IRINT_SET)); 
            interrupts = INTR_MODEM;   // 0x8
        }
        else 
		{
			if (pSerHead->useDMA)
			{
				if ((rxStatus & DDK_DMA_FLAGS_BUSY) == 0)
				{
					interrupts = INTR_RX;
					DEBUGMSG(ZONE_FLOW, (TEXT("GetIntr: RX SDMA completion\r\n")));
				}
				else if (pSerHead->awaitingTxDMACompBmp)
				{
					DEBUGMSG(1, (TEXT("GetIntr: pSerHead->awaitingTxDMACompBmp: %d\r\n"), pSerHead->awaitingTxDMACompBmp));
					for (i = 0; i < SERIAL_MAX_DESC_COUNT_TX; i++)
					{
						if ((1 << i) & pSerHead->awaitingTxDMACompBmp)
						{
							DDKSdmaGetBufDescStatus(pSerHead->SerialDmaChanTx, i, &txStatus);
							DEBUGMSG(1, (TEXT("GetIntr: Status: 0x%x\r\n"), txStatus));
							if ((txStatus & DDK_DMA_FLAGS_BUSY) == 0)
							{
								interrupts = INTR_TX;
								pSerHead->awaitingTxDMACompBmp &= ~(1 << i);
								DEBUGMSG(ZONE_FLOW, (TEXT("GetIntr: TX SDMA completion\r\n")));
							}
						}
					}
				}
				else
				{
					interrupts = INTR_NONE;
				}
			}
			else
				interrupts = INTR_NONE;
		}
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
        EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        intPndVal = INTR_NONE; // simulate no interrupt
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    if (pHWHead->AddTXIntr) {
        interrupts |= INTR_TX;
        pHWHead->AddTXIntr = FALSE;
        DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_GetIntrType - AddTXIntr 0x%x\r\n"),pHWHead->pUartReg->USR1));                
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("UART_USR1: 0x%x | UART_USR2: 0x%x\r\n"), pHWHead->pUartReg->USR1,  pHWHead->pUartReg->USR2));
    DEBUGMSG(ZONE_FUNCTION, (TEXT("SL_GetIntrType- 0x%X\r\n"),interrupts));

    return(interrupts);
}


//-----------------------------------------------------------------------------
//
// Function: SL_RxIntrHandler
//
// This function gets zero or more characters 
// from the hardware receive buffer and puts them 
// into the location pointed to by the pTargetBuffer 
// parameter. If there are no characters available 
// for reading, this function returns immediately. 
// This function is called in response to a receive 
// interrupt indication from the SL_GetInterruptType
// function.
//
// Parameters:
//      pContext 
//          [in] Pointer to device head.
//      pTargetBuffer 
//          [in] Pointer to the target buffer in which to put the data.
//      pByteNumber 
//          [in] Pointer to, on entry, the maximum 
//                number of bytes to read. On exit, the number of 
//                bytes read.
//
// Returns:  
//      The return value indicates the number of overruns 
//      detected. The actual number of dropped characters 
//      may be higher.
//
//-----------------------------------------------------------------------------
ULONG SL_RxIntrHandler( PVOID pContext, PUCHAR pTargetBuffer, ULONG *pByteNumber )
{
    PUART_INFO pHWHead = (PUART_INFO)pContext;
	PSER_INFO pSerHead = (PSER_INFO)pContext;
    ULONG RetVal = 0;
    ULONG TargetRoom = *pByteNumber;
    BOOL fRXFlag = FALSE;
    BOOL fReplaceparityErrors = FALSE;
    BOOL fNull;
    UCHAR cEvtChar, cRXChar;
    ULONG ulTemp=0;
    ULONG LineEvents = 0;

	// DMA related
	UINT32 Status = 0;
	UINT32 Mode = 0;
	ULONG copyCount, discardCount;

    DEBUGMSG(ZONE_READ, (TEXT("SL_RxIntrHandler+ : len %d. EvtChar 0x%x\r\n"), *pByteNumber,pHWHead->dcb.EvtChar));

    *pByteNumber = 0;

    cEvtChar = pHWHead->dcb.EvtChar;
    fNull = pHWHead->dcb.fNull;
    if (pHWHead->dcb.fErrorChar && pHWHead->dcb.fParity)
        fReplaceparityErrors = TRUE;

    try {
		if (pSerHead->useDMA == FALSE)
		{
			while (TargetRoom) {
				// See if there is another byte to be read
				SL_ReadLineStatus(pHWHead);

				if (pHWHead->sUSR2 & CSP_BITFVAL(UART_USR2_RDR, UART_USR2_RDR_SET)) {
					// Read the RX register
					ulTemp = INREG32(&pHWHead->pUartReg->URXD);

					//Discard the echo char for irda
					if (pHWHead->UseIrDA)
						if (pHWHead->ulDiscard) {
							pHWHead->ulDiscard--;
							continue;
						}
					//Check if a valid char
					if(ulTemp & CSP_BITFVAL(UART_URXD_ERR, UART_URXD_ERR_ERROR)) {
						DEBUGMSG(ZONE_ERROR,(TEXT("READ ERROR!!!  x%x\r\n"),ulTemp));
						if (ulTemp & CSP_BITFVAL(UART_URXD_FRMERR, UART_URXD_FRMERR_ERROR)) {  
							DEBUGMSG(ZONE_ERROR, (TEXT("Error frame\r\n")));
							pHWHead->CommErrors |= CE_FRAME;
							LineEvents |= EV_ERR;
						}

						if (ulTemp & CSP_BITFVAL(UART_URXD_PRERR, UART_URXD_PRERR_ERROR)) {
							DEBUGMSG(ZONE_ERROR, (TEXT("Error parity\r\n")));
							pHWHead->CommErrors |= CE_RXPARITY;
							LineEvents |= EV_ERR;
						}

						if (ulTemp & CSP_BITFVAL(UART_URXD_OVRRUN, UART_URXD_OVRRUN_LSH)) {
							DEBUGMSG(ZONE_ERROR, (TEXT("Error Overrun\r\n")));
							pHWHead->DroppedBytes++;
							pHWHead->CommErrors |= CE_OVERRUN;
							LineEvents |= EV_ERR;
						}

						if (ulTemp & CSP_BITFVAL(UART_URXD_BRK, UART_URXD_BRK_BREAK)) {
							DEBUGMSG(ZONE_ERROR, (TEXT("Error Break detect!!!\r\n")));
							LineEvents |= EV_BREAK;
						}

						// Let WaitCommEvent know about this error
						if (LineEvents) {
							pHWHead->EventCallback(pHWHead->pMDDContext, LineEvents);
						}                   //It's not a valid byte or error;
					}

					cRXChar = (UCHAR)ulTemp & UART_URXD_RX_DATA_MSK;
					DEBUGMSG(ZONE_READ, (TEXT("Read x%x\r\n"), cRXChar));

					// But we may want to discard it
					//Check DSR(DTR)
					if (pHWHead->dcb.fDsrSensitivity && (!pHWHead->bDSR)) {
						// Do nothing - byte gets discarded
						DEBUGMSG(ZONE_READ, (TEXT("Dropping byte because DSR is high\r\n")));
					}
					else if (!cRXChar && fNull) {
						// Do nothing - byte gets discarded
						DEBUGMSG(ZONE_READ, (TEXT("Dropping NULL byte due to fNull\r\n")));
					}
					else {
						// Do character replacement if parity error detected.
						//if ( fReplaceparityErrors && (pHWHead->sUSR1 & CSP_BITFVAL(UART_USR1_PARITYERR, UART_USR1_PARITYERR_SET)) ) {
						if (fReplaceparityErrors && (ulTemp & CSP_BITFVAL(UART_URXD_PRERR, UART_URXD_PRERR_ERROR))) {
							cRXChar = pHWHead->dcb.ErrorChar;
						}
						else {
							// See if we need to generate an EV_RXFLAG for the received char.
							if (cRXChar == cEvtChar) {
								DEBUGMSG(ZONE_READ, (TEXT("Evt Char x%x\r\n"), cEvtChar));
								fRXFlag = TRUE;
							}
						}
						// Finally, we can get byte, update status and save.
						*pTargetBuffer++ = cRXChar;

						DEBUGMSG(ZONE_READ,(TEXT("R%02x\r\n"),cRXChar));
						(*pByteNumber)++;
						--TargetRoom;

⌨️ 快捷键说明

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