📄 pdds3c2440_ser.cpp
字号:
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("CPdd16550::XmitInterruptHandler! Flow Off, Data Discard.\r\n")));
EnableXmitInterrupt(FALSE);
}
else {
DWORD dwWriteSize = GetWriteableSize();
DEBUGMSG(ZONE_THREAD|ZONE_WRITE,(TEXT("CPdd16550::XmitInterruptHandler! WriteableSize=%x to FIFO,dwDataAvaiable=%x\r\n"),
dwWriteSize,dwDataAvaiable));
for (DWORD dwByteWrite=0; dwByteWrite<dwWriteSize && dwDataAvaiable!=0;dwByteWrite++) {
m_pReg2440Uart->Write_UTXH(*pTxBuffer);
pTxBuffer ++;
dwDataAvaiable--;
}
DEBUGMSG(ZONE_THREAD|ZONE_WRITE,(TEXT("CPdd16550::XmitInterruptHandler! Write %d byte to FIFO\r\n"),dwByteWrite));
*pBuffLen = dwByteWrite;
EnableXmitInterrupt(TRUE);
}
ClearInterrupt(S2440UART_INT_TXD);
if (m_pReg2440Uart->Read_ULCON() & (0x1<<6))
while( (m_pReg2440Uart->Read_UFSTAT() >> 0x8 ) & 0x3f );
Rx_Pause(FALSE);
}
m_HardwareLock.Unlock();
}
void CPdd2440Uart::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_pReg2440Uart->Write_UTXH(ComChar);
bDone = TRUE;
}
else {
EnableXmitInterrupt(TRUE);
}
m_HardwareLock.Unlock();
if (!bDone)
WaitForSingleObject(m_XmitFlushDone, (ULONG)1000);
}
while (!bDone);
}
BOOL CPdd2440Uart::EnableXmitInterrupt(BOOL fEnable)
{
m_HardwareLock.Lock();
if (fEnable)
EnableInterrupt(S2440UART_INT_TXD);
else
DisableInterrupt(S2440UART_INT_TXD);
m_HardwareLock.Unlock();
return TRUE;
}
BOOL CPdd2440Uart::CancelXmit()
{
return InitXmit(TRUE);
}
static PAIRS s_HighWaterPairs[] = {
{0, 1 },
{1, 8 },
{2, 16 },
{3, 32 }
};
BYTE CPdd2440Uart::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 CPdd2440Uart::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 CPdd2440Uart::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_pReg2440Uart->Read_UFCON();
dwBit |= (1<<1);
dwBit &= ~(1<<0);
m_pReg2440Uart->Write_UFCON( dwBit);
// Set Trigger level to WaterMark.
dwBit &= ~(3<<4);
dwBit |= (uWarterMarkBit<<4);
m_pReg2440Uart->Write_UFCON(dwBit);
// Enable Receive FIFO.
dwBit &= ~(1<<1);
dwBit |= (1<<0);
m_pReg2440Uart->Write_UFCON(dwBit); // Xmit Fifo Reset Done..
m_pReg2440Uart->Read_UERSTAT(); // Clean Line Interrupt.
dwBit = m_pReg2440Uart->Read_UCON();
dwBit &= ~(3<<0);
dwBit |= (1<<0)|(1<<7)|(1<<8); // Enable Rx Timeout and Level Interrupt Trigger.
m_pReg2440Uart->Write_UCON(dwBit);
EnableInterrupt(S2440UART_INT_RXD | S2440UART_INT_ERR );
}
else {
DisableInterrupt(S2440UART_INT_RXD | S2440UART_INT_ERR );
}
m_HardwareLock.Unlock();
return TRUE;
}
ULONG CPdd2440Uart::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen)
{
DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("+CPdd2440Uart::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_pReg2440Uart->Read_UFSTAT();
DWORD dwNumRxInFifo = (ulUFSTATE & (0x3f<<0));
if ((ulUFSTATE & (1<<6))!=0) // Overflow. Use FIFO depth (16);
dwNumRxInFifo = SER2440_FIFO_DEPTH_RX;
DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("CPdd2440Uart::ReceiveInterruptHandler ulUFSTATE=%x,UTRSTAT=%x, dwNumRxInFifo=%X\r\n"),
ulUFSTATE, m_pReg2440Uart->Read_UTRSTAT(), dwNumRxInFifo));
if (dwNumRxInFifo) {
ASSERT((m_pReg2440Uart->Read_UTRSTAT () & (1<<0))!=0);
while (dwNumRxInFifo && dwRoomLeft) {
UCHAR uLineStatus = GetLineStatus();
UCHAR uData = m_pReg2440Uart->Read_URXH();
if (DataReplaced(&uData,(uLineStatus & UERSTATE_PARITY_ERROR)!=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("-CPdd2440Uart::ReceiveInterruptHandler pRxBuffer=%x,*pBufflen=%x,dwBytesDropped=%x\r\n"),
pRxBuffer,pBufflen!=NULL?*pBufflen:0,dwBytesDropped));
return dwBytesDropped;
}
ULONG CPdd2440Uart::CancelReceive()
{
m_bReceivedCanceled = TRUE;
m_HardwareLock.Lock();
InitReceive(TRUE);
m_HardwareLock.Unlock();
return 0;
}
BOOL CPdd2440Uart::InitModem(BOOL bInit)
{
m_HardwareLock.Lock();
m_pReg2440Uart->Write_UMCON((1<<0)); // Disable AFC and Set RTS as default.
m_HardwareLock.Unlock();
return TRUE;
}
ULONG CPdd2440Uart::GetModemStatus()
{
m_HardwareLock.Lock();
ULONG ulReturn =0 ;
ULONG Events = 0;
UINT8 ubModemStatus = (UINT8) m_pReg2440Uart->Read_UMSTAT();
m_HardwareLock.Unlock();
// Event Notification.
if (ubModemStatus & (1<<2))
Events |= EV_CTS;
if (Events!=0)
EventCallback(Events);
// Report Modem Status;
if ( ubModemStatus & (1<<0) )
ulReturn |= MS_CTS_ON;
return ulReturn;
}
void CPdd2440Uart::SetRTS(BOOL bSet)
{
m_HardwareLock.Lock();
ULONG ulData = m_pReg2440Uart->Read_UMCON();
if (bSet) {
ulData |= (1<<0);
}
else
ulData &= ~(1<<0);
m_pReg2440Uart->Write_UMCON(ulData);
m_HardwareLock.Unlock();
}
BOOL CPdd2440Uart::InitLine(BOOL bInit)
{
m_HardwareLock.Lock();
if (bInit) {
// Set 8Bit,1Stop,NoParity,Normal Mode.
//m_pReg2440Uart->Write_ULCON( (0x3<<0) | (0<<1) | (0<<3) | (0<<6) );
EnableInterrupt( S2440UART_INT_ERR );
}
else {
DisableInterrupt(S2440UART_INT_ERR );
}
m_HardwareLock.Unlock();
return TRUE;
}
BYTE CPdd2440Uart::GetLineStatus()
{
m_HardwareLock.Lock();
ULONG ulData = m_pReg2440Uart->Read_UERSTAT();
m_HardwareLock.Unlock();
ULONG ulError = 0;
if (ulData & (1<<0) ) {
ulError |= CE_OVERRUN;
}
if (ulData & (1<<1)) {
ulError |= CE_RXPARITY;
}
if (ulData & (1<<2)) {
ulError |= CE_FRAME;
}
if (ulError)
SetReceiveError(ulError);
if (ulData & (1<<3)) {
EventCallback(EV_BREAK);
}
return (UINT8)ulData;
}
void CPdd2440Uart::SetBreak(BOOL bSet)
{
m_HardwareLock.Lock();
ULONG ulData = m_pReg2440Uart->Read_UCON();
if (bSet)
ulData |= (1<<4);
else
ulData &= ~(1<<4);
m_pReg2440Uart->Write_UCON(ulData);
m_HardwareLock.Unlock();
}
BOOL CPdd2440Uart::SetBaudRate(ULONG BaudRate,BOOL /*bIrModule*/)
{
m_HardwareLock.Lock();
BOOL bReturn = m_pReg2440Uart->Write_BaudRate(BaudRate);
m_HardwareLock.Unlock();
return TRUE;
}
BOOL CPdd2440Uart::SetByteSize(ULONG ByteSize)
{
BOOL bRet = TRUE;
m_HardwareLock.Lock();
ULONG ulData = m_pReg2440Uart->Read_ULCON() & (~0x3);
switch ( ByteSize ) {
case 5:
break;
case 6:
ulData|= (1<<0);
break;
case 7:
ulData |= (2<<0);
break;
case 8:
ulData |= (3<<0);
break;
default:
bRet = FALSE;
break;
}
if (bRet) {
m_pReg2440Uart->Write_ULCON(ulData);
}
m_HardwareLock.Unlock();
return bRet;
}
BOOL CPdd2440Uart::SetParity(ULONG Parity)
{
BOOL bRet = TRUE;
m_HardwareLock.Lock();
ULONG ulData = m_pReg2440Uart->Read_ULCON() & (~(0x7<<3));
switch ( Parity ) {
case ODDPARITY:
ulData |= (4<<3);
break;
case EVENPARITY:
ulData |= (5<<3);
break;
case MARKPARITY:
ulData |= (6<<3);
break;
case SPACEPARITY:
ulData |= (7<<3);
break;
case NOPARITY:
break;
default:
bRet = FALSE;
break;
}
if (bRet) {
m_pReg2440Uart->Write_ULCON(ulData);
}
m_HardwareLock.Unlock();
return bRet;
}
BOOL CPdd2440Uart::SetStopBits(ULONG StopBits)
{
BOOL bRet = TRUE;
m_HardwareLock.Lock();
ULONG ulData = m_pReg2440Uart->Read_ULCON() & (~(0x1<<2));
switch ( StopBits ) {
case ONESTOPBIT :
break;
case TWOSTOPBITS :
ulData |= (0x1<<2);
break;
default:
bRet = FALSE;
break;
}
if (bRet) {
m_pReg2440Uart->Write_ULCON(ulData);
}
m_HardwareLock.Unlock();
return bRet;
}
void CPdd2440Uart::SetOutputMode(BOOL UseIR, BOOL Use9Pin)
{
m_HardwareLock.Lock();
CSerialPDD::SetOutputMode(UseIR, Use9Pin);
ULONG ulData = m_pReg2440Uart->Read_ULCON() & (~(0x1<<6));
ulData |= (UseIR?(0x1<<6):0);
m_pReg2440Uart->Write_ULCON(ulData);
m_HardwareLock.Unlock();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -