📄 pdds3c6410_ser.cpp
字号:
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 + -