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

📄 pdds3c6410_ser.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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("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();
}

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); // Xmit 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
		// 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;
		m_bReceivedCanceled = FALSE;
		m_HardwareLock.Lock();

		while (dwRoomLeft && !m_bReceivedCanceled)
		{
			ULONG ulUFSTATE = m_pReg6410Uart->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 = S3C6410_UART_FIFO_DEPTH;
			}
			DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("CPdd6410Uart::ReceiveInterruptHandler ulUFSTATE=%x,UTRSTAT=%x, dwNumRxInFifo=%X\r\n"),
				ulUFSTATE, m_pReg6410Uart->Read_UTRSTAT(), dwNumRxInFifo));
			if (dwNumRxInFifo)
			{
				ASSERT((m_pReg6410Uart->Read_UTRSTAT() & UART_RX_BUFFER_STATUS_MASK)!= UART_RX_BUFFER_EMPTY);
				while (dwNumRxInFifo && dwRoomLeft)
				{
					UCHAR uLineStatus = GetLineStatus();
					UCHAR uData = m_pReg6410Uart->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("-CPdd6410Uart::ReceiveInterruptHandler pRxBuffer=%x,*pBufflen=%x,dwBytesDropped=%x\r\n"),
		pRxBuffer,pBufflen!=NULL?*pBufflen:0,dwBytesDropped));
	return dwBytesDropped;
}
ULONG   CPdd6410Uart::CancelReceive()
{
	m_bReceivedCanceled = TRUE;
	m_HardwareLock.Lock();   
	InitReceive(TRUE);
	m_HardwareLock.Unlock();
	return 0;
}
BOOL    CPdd6410Uart::InitModem(BOOL bInit)
{
	m_HardwareLock.Lock();
	m_pReg6410Uart->Write_UMCON( m_pReg6410Uart->Read_UMCON()
		|UART_MCR_AUTO_FLOW_DISABLE
		|UART_MCR_MODEM_INTERRUPT_ENABLE
		|UART_MCR_SET_RTS); 
	m_HardwareLock.Unlock();
	return TRUE;
}

ULONG   CPdd6410Uart::GetModemStatus()
{
	m_HardwareLock.Lock();    
	ULONG ulReturn =0 ;
	ULONG Events = 0;
	UINT8 ubModemStatus = (UINT8) m_pReg6410Uart->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    CPdd6410Uart::SetRTS(BOOL bSet)
{
	m_HardwareLock.Lock();
	ULONG ulData = m_pReg6410Uart->Read_UMCON();
	if (bSet)
	{
		ulData |= (UART_MCR_SET_RTS);
	}
	else
	{
		ulData &= ~(UART_MCR_SET_RTS);
	}
	m_pReg6410Uart->Write_UMCON(ulData);
	m_HardwareLock.Unlock();

}
BOOL CPdd6410Uart::InitLine(BOOL bInit)
{
	m_HardwareLock.Lock();
	if  (bInit)
	{
		// Set 8Bit,1Stop,NoParity,Normal Mode.
		//m_pReg6410Uart->Write_ULCON( (0x3<<0) | (0<<1) | (0<<3) | (0<<6) );
		EnableInterrupt( S6410UART_INT_ERR );
	}
	else
	{
		DisableInterrupt(S6410UART_INT_ERR );
	}
	m_HardwareLock.Unlock();
	return TRUE;
}
BYTE CPdd6410Uart::GetLineStatus()
{
	m_HardwareLock.Lock();
	ULONG ulData = m_pReg6410Uart->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    CPdd6410Uart::SetBreak(BOOL bSet)
{
	m_HardwareLock.Lock();
	ULONG ulData = m_pReg6410Uart->Read_UCON();
	if (bSet)
	{
		ulData |= (UART_BREAK_SIGNAL_ENABLE);
	}
	else
	{
		ulData &= ~(UART_BREAK_SIGNAL_ENABLE);
	}
	m_pReg6410Uart->Write_UCON(ulData);
	m_HardwareLock.Unlock();      
}
BOOL    CPdd6410Uart::SetBaudRate(ULONG BaudRate,BOOL /*bIrModule*/)
{
	m_HardwareLock.Lock();
	BOOL bReturn = m_pReg6410Uart->Write_BaudRate(BaudRate);
	m_HardwareLock.Unlock();      
	return TRUE;
}
BOOL    CPdd6410Uart::SetByteSize(ULONG ByteSize)
{
	BOOL bRet = TRUE;
	m_HardwareLock.Lock();
	ULONG ulData = (m_pReg6410Uart->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_pReg6410Uart->Write_ULCON(ulData);
	}
	m_HardwareLock.Unlock();
	return bRet;
}
BOOL    CPdd6410Uart::SetParity(ULONG Parity)
{
	BOOL bRet = TRUE;
	m_HardwareLock.Lock();
	ULONG ulData = (m_pReg6410Uart->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_pReg6410Uart->Write_ULCON(ulData);
	}
	m_HardwareLock.Unlock();
	return bRet;
}
BOOL    CPdd6410Uart::SetStopBits(ULONG StopBits)
{
	BOOL bRet = TRUE;
	m_HardwareLock.Lock();
	ULONG ulData = (m_pReg6410Uart->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_pReg6410Uart->Write_ULCON(ulData);
	}
	m_HardwareLock.Unlock();
	return bRet;
}
void    CPdd6410Uart::SetOutputMode(BOOL UseIR, BOOL Use9Pin)
{
	m_HardwareLock.Lock();
	CSerialPDD::SetOutputMode(UseIR, Use9Pin);
	ULONG ulData = (m_pReg6410Uart->Read_ULCON() & (~(UART_LCR_MODE_MASK)));
	ulData |= (UseIR?(UART_LCR_IR_MODE):(UART_LCR_NORMAL_MODE));
	m_pReg6410Uart->Write_ULCON(ulData);
	m_HardwareLock.Unlock();
}

⌨️ 快捷键说明

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