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

📄 pdds3c6410_ser.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    }
                    if ((dwData & S6410UART_INT_ERR)!=0)
                    {
                        interrupts |= INTR_LINE | INTR_RX;
                    }
                    if ((dwData & S6410UART_INT_MODEM)!=0)
                    {
                        interrupts |=INTR_MODEM;
                    }
                    
                    NotifyPDDInterrupt( (INTERRUPT_TYPE)interrupts );
                    
                    ClearInterrupt(dwData);
                }
                else
                {
                    break;
                }
            }

            m_HardwareLock.Unlock();   

            InterruptDone(m_dwSysIntr);
        }
        else
        {
            DEBUGMSG(ZONE_THREAD,(TEXT(" CPdd6410Uart::ThreadRun timeout INT=%x,MASK=%d\r\n"),m_pReg6410Uart->Read_UINTP()/*m_pReg6410Uart->Read_UINTSP()*/, m_pReg6410Uart->Read_UINTM()) );
            ASSERT(FALSE);
        }
    }

    return 1;
}
BOOL CPdd6410Uart::InitialEnableInterrupt(BOOL bEnable )
{
    m_HardwareLock.Lock();
    if (bEnable)
    {
        EnableInterrupt(S6410UART_INT_RXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
    }
    else
    {
        DisableInterrupt(S6410UART_INT_RXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
    }
    m_HardwareLock.Unlock();
    return TRUE;
}

BOOL  CPdd6410Uart::InitXmit(BOOL bInit)
{
    DWORD dwTicks = 0;
    DWORD dwUTRState;

    if (bInit)
    { 
        m_HardwareLock.Lock();    
        DWORD dwBit = m_pReg6410Uart->Read_UCON();
#if EPLL_CLK
        // Set UART CLK.
        dwBit &= ~(UART_CS_MASK);
        dwBit |= (UART_CS_EPLLCLK);
#endif
        if (m_ClockSelectValid) {
            dwBit &= ~(UART_CS_MASK);
            dwBit |= (m_ClockSelect);
        }

 
        // Set Tx Inerrupt Request Type, Tx Interrupt/Polling Mode.
        dwBit &= ~(UART_TX_INT_TYPE_MASK|UART_TX_MODE_MASK);
        dwBit |= (UART_TX_INT_TYPE_LEVEL|UART_TX_INT_POLL);
        m_pReg6410Uart->Write_UCON(dwBit );

        dwBit = m_pReg6410Uart->Read_UFCON();
        // Reset Xmit Fifo.
        dwBit |= (UART_FCR_TX_FIFO_RESET);
        dwBit &= ~(UART_FCR_FIFO_ENABLE);
        m_pReg6410Uart->Write_UFCON( dwBit);
        // Set Trigger level to 16. 
        dwBit &= ~(UART_FCR_TX_FIFO_TRIG_MASK);
        dwBit |= (UART_FCR_TX_FIFO_TRIG_16);//16
        m_pReg6410Uart->Write_UFCON(dwBit); 
        // Enable Xmit FIFO.
        dwBit &= ~(UART_FCR_TX_FIFO_RESET);
        dwBit |= (UART_FCR_FIFO_ENABLE);
        m_pReg6410Uart->Write_UFCON(dwBit); // Xmit Fifo Reset Done..
        m_HardwareLock.Unlock();
#ifdef USE_DMA
	if(m_dwTXDMAEnable)
	{
		InitXmitDMA();
	}
#endif 
    }
    else 
    { // Make Sure data has been trasmit out.
        // We have to make sure the xmit is complete because MDD will shut down the device after this return
        while (dwTicks < TIMEOUT_TX_EMPTY && ((dwUTRState = m_pReg6410Uart->Read_UTRSTAT()) & (UART_TRANSMITTER_STATUS_MASK | UART_TX_BUFFER_STATUS_MASK))
            != (UART_TRANSMITTER_EMPTY | UART_TX_BUFFER_EMPTY))
        { // Transmitter empty is not true
            DEBUGMSG(ZONE_THREAD|ZONE_WRITE, (TEXT("CPdd6410Uart::InitXmit! Wait for UTRSTAT=%x clear.\r\n"), dwUTRState));
            Sleep(5);
            dwTicks +=5;
        }
    }
    return TRUE;
}
DWORD   CPdd6410Uart::GetWriteableSize()
{
    DWORD dwWriteSize = 0;
    DWORD dwUfState = m_pReg6410Uart->Read_UFSTAT() ;
    if ((dwUfState & UART_FSR_TX_FIFO_MASK)==UART_FSR_TX_FIFO_NOT_FULL)
    { // It is not full.
        dwUfState = ((dwUfState & UART_FSR_TX_FIFO_COUNT_MASK) >> UART_FSR_TX_FIFO_COUNT_SHFIT); // It is fifo count.
        if (dwUfState < S3C6410_UART_FIFO_DEPTH-1)
        {
            dwWriteSize = S3C6410_UART_FIFO_DEPTH-1 - dwUfState;
        }
    }
    return dwWriteSize;
}

#ifdef USE_DMA
void    CPdd6410Uart::XmitInterruptHandler(PUCHAR pTxBuffer, ULONG *pBuffLen)
{
    BOOL bRet;
    PREFAST_DEBUGCHK(pBuffLen!=NULL);
    m_HardwareLock.Lock();

	//wait until TX FIFO empty 
	// 6ms : 38400 baudrate/64Byte
	// 85us : 3M baudrate/64Byte	
	// It affects when BT power on and off at low baudrate	
	if((m_dwTXDMAEnable==1) && (*pBuffLen < UART_TX_FIFO_LEN))
	{
		while(((m_pReg6410Uart->Read_UFSTAT()>>8) & 0x3f))
		{
	            	RETAILMSG(FALSE, (TEXT("[UART] Wait \r\n")));
		}
	} 
    
    if (*pBuffLen == 0)
    {
        EnableXmitInterrupt(FALSE);
    }
    else
    {
        DEBUGCHK(pTxBuffer);
        PulseEvent(m_XmitFlushDone);
        DWORD dwDataAvaiable = *pBuffLen;
        *pBuffLen = 0;
        DMA_ERROR dma_error_value = DMA_SUCCESS;

        Rx_Pause(TRUE);
        if ((m_DCB.fOutxCtsFlow && IsCTSOff()) ||(m_DCB.fOutxDsrFlow && IsDSROff()))
        { // We are in flow off
            RETAILMSG(FALSE, (TEXT("CPddS3CXUart::XmitInterruptHandler! Flow Off, Data Discard.\r\n")));
            EnableXmitInterrupt(FALSE);
        }
        else
        {
			if((m_dwTXDMAEnable==1)&&(dwDataAvaiable> UART_TX_FIFO_LEN/*UART_TX_FIFO_LEN*/))			
			{
				DWORD dwDmaLen = (dwDataAvaiable > Buffer_Mem_Size)? Buffer_Mem_Size:dwDataAvaiable;
				
				RETAILMSG(0,(TEXT("[UART] Thread for TX : USE DMA (TxCount : %d) \r\n"),dwDmaLen));

				if(dwDmaLen > 0)
				{
					bRet = StartXmitDMA(pTxBuffer, dwDmaLen);
					if(!bRet)
					{
						goto LEAVEWRITE;
					}
                                dwDataAvaiable -= dwDmaLen;
					pTxBuffer = (PUCHAR)(((PUINT) pTxBuffer) + dwDmaLen);
				}

				*pBuffLen = dwDmaLen;
                		EnableXmitInterrupt(TRUE); 

				
   }
			
   else
   {
				DWORD dwWriteSize = GetWriteableSize();

				RETAILMSG(0,(TEXT("[UART] XmitInterruptHandler! WriteableSize=%x to FIFO,dwDataAvaiable=%x\r\n"),
					dwWriteSize,dwDataAvaiable));

                for (DWORD dwByteWrite=0; dwByteWrite<dwWriteSize && dwDataAvaiable!=0;dwByteWrite++)
                {
                    m_pReg6410Uart->Write_UTXH(*pTxBuffer);
                    pTxBuffer ++;
                    dwDataAvaiable--;
                }

                RETAILMSG(0,(TEXT("[UART] XmitInterruptHandler! Write %d byte to FIFO\r\n"),dwByteWrite));

                *pBuffLen = dwByteWrite;
                EnableXmitInterrupt(TRUE);        
            }                

        }
LEAVEWRITE:
        ClearInterrupt(S6410UART_INT_TXD);
		
        if (m_pReg6410Uart->Read_ULCON() & (1 << 6))
        {
            while((m_pReg6410Uart->Read_UFSTAT() & (0x3F << 8)) >> (8));
        }
        Rx_Pause(FALSE);
    }
    m_HardwareLock.Unlock();
   }
#else//#ifdef USE_DMA
void    CPdd6410Uart::XmitInterruptHandler(PUCHAR pTxBuffer, ULONG *pBuffLen)
{
    PREFAST_DEBUGCHK(pBuffLen!=NULL);
    m_HardwareLock.Lock();    
    if (*pBuffLen == 0)
    { 
        EnableXmitInterrupt(FALSE);
    }
    else
    {
        DEBUGCHK(pTxBuffer);
        PulseEvent(m_XmitFlushDone);
        DWORD dwDataAvaiable = *pBuffLen;
        *pBuffLen = 0;

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

        if (m_pReg6410Uart->Read_ULCON() & UART_LCR_IR_MODE)
        {
            while((m_pReg6410Uart->Read_UFSTAT() & UART_FSR_TX_FIFO_COUNT_MASK) >> UART_FSR_TX_FIFO_COUNT_SHFIT);
        }
        Rx_Pause(FALSE);
    }
    m_HardwareLock.Unlock();
}
#endif //#ifdef USE_DMA

void    CPdd6410Uart::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_pReg6410Uart->Write_UTXH(ComChar);
            bDone = TRUE;
        }
        else
        {
            EnableXmitInterrupt(TRUE);
        }
            m_HardwareLock.Unlock();
        if (!bDone)
        {
            WaitForSingleObject(m_XmitFlushDone, (ULONG)1000);
        }
    }while (!bDone);
}
BOOL    CPdd6410Uart::EnableXmitInterrupt(BOOL fEnable)
{
    m_HardwareLock.Lock();
    if (fEnable)
    {
        EnableInterrupt(S6410UART_INT_TXD);
    }
    else
    {
        DisableInterrupt(S6410UART_INT_TXD);
    }
    m_HardwareLock.Unlock();
    return TRUE; 
}
BOOL  CPdd6410Uart::CancelXmit()
{
    return InitXmit(TRUE);     
}
static PAIRS s_HighWaterPairs[] =
{
    {0, 1 },
    {1, 8 },
    {2, 16 },
    {3, 32 }
};

BYTE  CPdd6410Uart::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   CPdd6410Uart::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    CPdd6410Uart::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_pReg6410Uart->Read_UFCON();
        dwBit |= (UART_FCR_RX_FIFO_RESET);
        dwBit &= ~(UART_FCR_FIFO_ENABLE);
        m_pReg6410Uart->Write_UFCON( dwBit);
        // Set Trigger level to WaterMark.
        dwBit &= ~(UART_FCR_RX_FIFO_TRIG_MASK);
        dwBit |= (uWarterMarkBit<<4);
        m_pReg6410Uart->Write_UFCON(dwBit); 
        // Enable Receive FIFO.
        dwBit &= ~(UART_FCR_RX_FIFO_RESET);
        dwBit |= (UART_FCR_FIFO_ENABLE);
        m_pReg6410Uart->Write_UFCON(dwBit); // Receive FIFO Reset Done..
        m_pReg6410Uart->Read_UERSTAT(); // Clean Line Interrupt.
        dwBit = m_pReg6410Uart->Read_UCON();
#if EPLL_CLK
        // Set UART CLK.
        dwBit &= ~(UART_CS_MASK);
        dwBit |= (UART_CS_EPLLCLK);
#endif
        if (m_ClockSelectValid) {
            dwBit &= ~(UART_CS_MASK);
            dwBit |= (m_ClockSelect);
        }
        // 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_pReg6410Uart->Write_UCON(dwBit);
        EnableInterrupt(S6410UART_INT_RXD | S6410UART_INT_ERR );
    }
    else
    {
        DisableInterrupt(S6410UART_INT_RXD | S6410UART_INT_ERR );
    }
    m_HardwareLock.Unlock();
    return TRUE;
}
ULONG   CPdd6410Uart::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen)
{
    DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("+CPdd6410Uart::ReceiveInterruptHandler pRxBuffer=%x,*pBufflen=%x\r\n"),
        pRxBuffer,pBufflen!=NULL?*pBufflen:0));
    DWORD dwBytesDropped = 0;
    if (pRxBuffer && pBufflen )
    {
        DWORD dwBytesStored = 0 ;
        DWORD dwRoomLeft = *pBufflen;

⌨️ 快捷键说明

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