pdds3c2450_ser.cpp.keep

来自「S3C2450BSP开发包,里面有很多资料。可以提供大家参考下。有什么需要解决问」· KEEP 代码 · 共 951 行 · 第 1/2 页

KEEP
951
字号
    if (*pBuffLen == 0)
    { 
        EnableXmitInterrupt(FALSE);
    }
    else
    {
        DEBUGCHK(pTxBuffer);
        PulseEvent(m_XmitFlushDone);

        DWORD dwDataAvaiable = *pBuffLen;
        *pBuffLen = 0;

        Rx_Pause(TRUE);
        if ((m_DCB.fOutxCtsFlow && IsCTSOff()) ||(m_DCB.fOutxDsrFlow && IsDSROff()))
        { // We are in flow off
            DEBUGMSG(ZONE_THREAD|ZONE_WRITE, (TEXT("CPdd2450Uart::XmitInterruptHandler! Flow Off, Data Discard.\r\n")));
            EnableXmitInterrupt(FALSE);
        }
        else
        {
            DWORD dwWriteSize = GetWriteableSize();
            DEBUGMSG(ZONE_THREAD|ZONE_WRITE,(TEXT("CPdd2450Uart::XmitInterruptHandler! WriteableSize=%x to FIFO,dwDataAvaiable=%x\r\n"),
                    dwWriteSize,dwDataAvaiable));
            for (DWORD dwByteWrite=0; dwByteWrite<dwWriteSize && dwDataAvaiable!=0;dwByteWrite++) 
            {
                m_pReg2450Uart->Write_UTXH(*pTxBuffer);
                pTxBuffer ++;
                dwDataAvaiable--;
            }
            DEBUGMSG(ZONE_THREAD|ZONE_WRITE,(TEXT("CPdd2450Uart::XmitInterruptHandler! Write %d byte to FIFO\r\n"),dwByteWrite));
            *pBuffLen = dwByteWrite;
            EnableXmitInterrupt(TRUE);        
        }
        ClearInterrupt(S2450UART_INT_TXD);

        if (m_pReg2450Uart->Read_ULCON() & UART_LCR_IR_MODE)
        {
             while((m_pReg2450Uart->Read_UFSTAT() & UART_FSR_TX_FIFO_COUNT_MASK) >> UART_FSR_TX_FIFO_COUNT_SHFIT);
        }
		Rx_Pause(FALSE);
    }
    m_HardwareLock.Unlock();
}

void    CPdd2450Uart::XmitComChar(UCHAR ComChar)
{
    // This function has to poll until the Data can be sent out.
    BOOL bDone = FALSE;
    do 
    {
        m_HardwareLock.Lock(); 
        if ( GetWriteableSize()!=0 )
        {  // If not full 
            m_pReg2450Uart->Write_UTXH(ComChar);
            bDone = TRUE;
        }
        else
        {
            EnableXmitInterrupt(TRUE);
        }
        m_HardwareLock.Unlock();
        if (!bDone)
        {
           WaitForSingleObject(m_XmitFlushDone, (ULONG)1000);
        }
    }while (!bDone);
}

BOOL    CPdd2450Uart::EnableXmitInterrupt(BOOL fEnable)
{
    m_HardwareLock.Lock();
    if (fEnable)
    {
        EnableInterrupt(S2450UART_INT_TXD);
    }
    else
    {
        DisableInterrupt(S2450UART_INT_TXD);
    }
    m_HardwareLock.Unlock();
    return TRUE;
}

BOOL  CPdd2450Uart::CancelXmit()
{
    return InitXmit(TRUE);     
}

static PAIRS s_HighWaterPairs[] =
{
    {0, 1 },
    {1, 8 },
    {2, 16 },
    {3, 32 }
};

BYTE  CPdd2450Uart::GetWaterMarkBit()
{
    BYTE bReturnKey = (BYTE)s_HighWaterPairs[0].Key;
    for (DWORD dwIndex = dim(s_HighWaterPairs)-1 ; dwIndex != 0; dwIndex --)
    {
        if (m_dwWaterMark >= s_HighWaterPairs[dwIndex].AssociatedValue)
        {
            bReturnKey = (BYTE)s_HighWaterPairs[dwIndex].Key;
            break;
        }
    }
    return bReturnKey;
}

DWORD   CPdd2450Uart::GetWaterMark()
{
    BYTE bReturnValue = (BYTE)s_HighWaterPairs[0].AssociatedValue;
    for (DWORD dwIndex = dim(s_HighWaterPairs)-1 ; dwIndex != 0; dwIndex --) 
    {
        if (m_dwWaterMark >= s_HighWaterPairs[dwIndex].AssociatedValue)
        {
            bReturnValue = (BYTE)s_HighWaterPairs[dwIndex].AssociatedValue;
            break;
        }
    }
    return bReturnValue;
}

// Receive
BOOL    CPdd2450Uart::InitReceive(BOOL bInit)
{
    m_HardwareLock.Lock();    
    if (bInit)
    {         
        BYTE uWarterMarkBit = GetWaterMarkBit();
        if (uWarterMarkBit> 3)
        {
            uWarterMarkBit = 3;
        }

        // Setup Receive FIFO.
        // Reset Receive FIFO.
        DWORD dwBit = m_pReg2450Uart->Read_UFCON();
        dwBit |= (UART_FCR_RX_FIFO_RESET);
        dwBit &= ~(UART_FCR_FIFO_ENABLE);
        m_pReg2450Uart->Write_UFCON( dwBit);

        // Set Trigger level to WaterMark.
        dwBit &= ~(UART_FCR_RX_FIFO_TRIG_MASK);
        dwBit |= (uWarterMarkBit<<4);
        m_pReg2450Uart->Write_UFCON(dwBit);

        // Enable Receive FIFO.
		dwBit &= ~(UART_FCR_RX_FIFO_RESET);
		dwBit |= (UART_FCR_FIFO_ENABLE);
        m_pReg2450Uart->Write_UFCON(dwBit); // Xmit Fifo Reset Done..

        m_pReg2450Uart->Read_UERSTAT(); // Clean Line Interrupt.
        dwBit = m_pReg2450Uart->Read_UCON();

#if EPLL_CLK
		// Set UART CLK.
		dwBit &= ~(UART_CS_MASK);
		dwBit |= (UART_CS_EPLLCLK);
#endif
		// Set Rx Inerrupt Request Type, Rx Timeout, Rx Interrupt/Polling Mode.
		dwBit &= ~(UART_RX_INT_TYPE_MASK|UART_RX_TIMEOUT_MASK|UART_RX_MODE_MASK);
		dwBit |= (UART_RX_INT_TYPE_LEVEL|UART_RX_TIMEOUT_ENABLE|UART_RX_INT_POLL);
        m_pReg2450Uart->Write_UCON(dwBit);

        EnableInterrupt(S2450UART_INT_RXD | S2450UART_INT_ERR );
    }
    else
    {
        DisableInterrupt(S2450UART_INT_RXD | S2450UART_INT_ERR );
    }
    m_HardwareLock.Unlock();
    return TRUE;
}

ULONG   CPdd2450Uart::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen)
{
    DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("+CPdd2450Uart::ReceiveInterruptHandler pRxBuffer=%x,*pBufflen=%x\r\n"),
        pRxBuffer,pBufflen!=NULL?*pBufflen:0));
    DWORD dwBytesDropped = 0;
    if (pRxBuffer && pBufflen )
    {
        DWORD dwBytesStored = 0 ;
        DWORD dwRoomLeft = *pBufflen;
        m_bReceivedCanceled = FALSE;
        m_HardwareLock.Lock();

        while (dwRoomLeft && !m_bReceivedCanceled)
        {
            ULONG ulUFSTATE = m_pReg2450Uart->Read_UFSTAT();
            DWORD dwNumRxInFifo = ((ulUFSTATE & UART_FSR_RX_FIFO_COUNT_MASK) >> UART_FSR_RX_FIFO_COUNT_SHIFT);
            if ((ulUFSTATE & (UART_FSR_RX_FIFO_MASK))== UART_FSR_RX_FIFO_FULL) // Overflow.;
            {
                dwNumRxInFifo = S3C2450_UART_FIFO_DEPTH;
            }
            DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("CPdd2450Uart::ReceiveInterruptHandler ulUFSTATE=%x,UTRSTAT=%x, dwNumRxInFifo=%X\r\n"),
                ulUFSTATE, m_pReg2450Uart->Read_UTRSTAT(), dwNumRxInFifo));
            if (dwNumRxInFifo)
            {
                ASSERT((m_pReg2450Uart->Read_UTRSTAT() & UART_RX_BUFFER_STATUS_MASK)!= UART_RX_BUFFER_EMPTY);
                while (dwNumRxInFifo && dwRoomLeft)
                {
                    UCHAR uLineStatus = GetLineStatus();
                    UCHAR uData = m_pReg2450Uart->Read_URXH();
                    if (DataReplaced(&uData,(uLineStatus & UART_LSR_PE)!=0)) 
                    {
                        *pRxBuffer++ = uData;
                        dwRoomLeft--;
                        dwBytesStored++;                    
                    }
                    dwNumRxInFifo --;
                }
            }
            else
            {
                break;
            }
        }
        if (m_bReceivedCanceled)
        {
            dwBytesStored = 0;
        }

        m_HardwareLock.Unlock();
        *pBufflen = dwBytesStored;
    }
    else
    {
        ASSERT(FALSE);
    }
    DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("-CPdd2450Uart::ReceiveInterruptHandler pRxBuffer=%x,*pBufflen=%x,dwBytesDropped=%x\r\n"),
        pRxBuffer,pBufflen!=NULL?*pBufflen:0,dwBytesDropped));
    return dwBytesDropped;
}

ULONG   CPdd2450Uart::CancelReceive()
{
    m_bReceivedCanceled = TRUE;
    m_HardwareLock.Lock();   
    InitReceive(TRUE);
    m_HardwareLock.Unlock();
    return 0;
}

BOOL    CPdd2450Uart::InitModem(BOOL bInit)
{
    m_HardwareLock.Lock(); 
	m_pReg2450Uart->Write_UMCON( m_pReg2450Uart->Read_UMCON()
		|UART_MCR_AUTO_FLOW_DISABLE
		|UART_MCR_SET_RTS);
    m_HardwareLock.Unlock();
    return TRUE;
}

ULONG   CPdd2450Uart::GetModemStatus()
{
    m_HardwareLock.Lock();    
    ULONG ulReturn =0 ;
    ULONG Events = 0;
    UINT8 ubModemStatus = (UINT8) m_pReg2450Uart->Read_UMSTAT();
    m_HardwareLock.Unlock();

    // Event Notification.
    if (ubModemStatus & (UART_MSR_DCTS))
    {
        Events |= EV_CTS;
    }
    if (Events!=0)
    {
        EventCallback(Events);
    }

    // Report Modem Status;
    if ( ubModemStatus & (UART_MSR_CTS))
    {
        ulReturn |= MS_CTS_ON;
    }
    return ulReturn;
}

void    CPdd2450Uart::SetRTS(BOOL bSet)
{
    m_HardwareLock.Lock();
    ULONG ulData = m_pReg2450Uart->Read_UMCON();
    if (bSet)
    {
        ulData |= (UART_MCR_SET_RTS);
    }
    else
    {
        ulData &= ~(UART_MCR_SET_RTS);
    }
    m_pReg2450Uart->Write_UMCON(ulData);
    m_HardwareLock.Unlock();
}

BOOL CPdd2450Uart::InitLine(BOOL bInit)
{
    m_HardwareLock.Lock();
    if  (bInit)
    {
        // Set 8Bit,1Stop,NoParity,Normal Mode.
        //m_pReg2450Uart->Write_ULCON( (0x3<<0) | (0<<1) | (0<<3) | (0<<6) );
        EnableInterrupt( S2450UART_INT_ERR );
    }
    else
    {
        DisableInterrupt(S2450UART_INT_ERR );
    }
    m_HardwareLock.Unlock();
    return TRUE;
}

BYTE CPdd2450Uart::GetLineStatus()
{
    m_HardwareLock.Lock();
    ULONG ulData = m_pReg2450Uart->Read_UERSTAT();
    m_HardwareLock.Unlock();  
    ULONG ulError = 0;

    if (ulData & (UART_LSR_OE) )
    {
        ulError |=  CE_OVERRUN;
    }
    if (ulData & (UART_LSR_PE))
    {
        ulError |= CE_RXPARITY;
    }
    if (ulData & (UART_LSR_FE))
    {
        ulError |=  CE_FRAME;
    }

    if (ulError)
    {
        SetReceiveError(ulError);
    }

    if (ulData & (UART_LSR_BI))
    {
         EventCallback(EV_BREAK);
    }
    return (UINT8)ulData;    
}

void    CPdd2450Uart::SetBreak(BOOL bSet)
{
    m_HardwareLock.Lock();
    ULONG ulData = m_pReg2450Uart->Read_UCON();
    if (bSet)
    {
         ulData |= (UART_BREAK_SIGNAL_ENABLE);
    }
    else
    {
        ulData &= ~(UART_BREAK_SIGNAL_ENABLE);
    }
    m_pReg2450Uart->Write_UCON(ulData);
    m_HardwareLock.Unlock();      
}

BOOL    CPdd2450Uart::SetBaudRate(ULONG BaudRate,BOOL /*bIrModule*/)
{
    m_HardwareLock.Lock();
    BOOL bReturn = m_pReg2450Uart->Write_BaudRate(BaudRate);
    m_HardwareLock.Unlock();      
    return TRUE;
}

BOOL    CPdd2450Uart::SetByteSize(ULONG ByteSize)
{
    BOOL bRet = TRUE;
    m_HardwareLock.Lock();

    ULONG ulData = (m_pReg2450Uart->Read_ULCON() & (~(UART_LCR_DATA_LENGTH_MASK)));
    switch ( ByteSize )
    {
    case 5:
        ulData |= (UART_LCR_DATA_LENGTH_5BIT);
        break;
    case 6:
        ulData |= (UART_LCR_DATA_LENGTH_6BIT);
        break;
    case 7:
        ulData |= (UART_LCR_DATA_LENGTH_7BIT);
        break;
    case 8:
        ulData |= (UART_LCR_DATA_LENGTH_8BIT);
        break;
    default:
        bRet = FALSE;
        break;
    }
    if (bRet)
    {
        m_pReg2450Uart->Write_ULCON(ulData);
    }
    m_HardwareLock.Unlock();
    return bRet;
}

BOOL    CPdd2450Uart::SetParity(ULONG Parity)
{
    BOOL bRet = TRUE;
    m_HardwareLock.Lock();
    ULONG ulData = (m_pReg2450Uart->Read_ULCON() & (~(UART_LCR_PARITY_MASK)));

    switch ( Parity )
    {
    case ODDPARITY:
        ulData |= (UART_LCR_PARITY_ODD);
        break;
    case EVENPARITY:
        ulData |= (UART_LCR_PARITY_EVEN);
        break;
    case MARKPARITY:
        ulData |= (UART_LCR_PARITY_FORCE_1);
        break;
    case SPACEPARITY:
        ulData |= (UART_LCR_PARITY_FORCE_0);
        break;
    case NOPARITY:
        break;
    default:
        bRet = FALSE;
        break;
    }

    if (bRet)
    {
        m_pReg2450Uart->Write_ULCON(ulData);
    }
    m_HardwareLock.Unlock();
    return bRet;
}

BOOL    CPdd2450Uart::SetStopBits(ULONG StopBits)
{
    BOOL bRet = TRUE;
    m_HardwareLock.Lock();
	ULONG ulData = (m_pReg2450Uart->Read_ULCON() & (~(UART_LCR_STOPBIT_MASK)));

    switch ( StopBits )
    {
    case ONESTOPBIT :
        ulData |= (UART_LCR_1_STOPBIT);
        break;
    case TWOSTOPBITS :
        ulData |= (UART_LCR_2_STOPBITS);
        break;
    default:
        bRet = FALSE;
        break;
    }

    if (bRet)
    {
        m_pReg2450Uart->Write_ULCON(ulData);
    }
    m_HardwareLock.Unlock();
    return bRet;
}

void    CPdd2450Uart::SetOutputMode(BOOL UseIR, BOOL Use9Pin)
{
    m_HardwareLock.Lock();
    CSerialPDD::SetOutputMode(UseIR, Use9Pin);
    ULONG ulData = (m_pReg2450Uart->Read_ULCON() & (~(UART_LCR_MODE_MASK)));
    ulData |= (UseIR?(UART_LCR_IR_MODE):(UART_LCR_NORMAL_MODE));
    m_pReg2450Uart->Write_ULCON(ulData);
    m_HardwareLock.Unlock();
}

⌨️ 快捷键说明

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