📄 pdds3c6410_ser.cpp
字号:
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)
{
if (m_AutoFlowEnabled) {
return;
}
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)
{
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*/)
{
DWORD dwBit;
m_HardwareLock.Lock();
if (m_ClockSelectValid) {
dwBit = m_pReg6410Uart->Read_UCON();
dwBit &= ~(UART_CS_MASK);
if (BaudRate < 10*115200) {
m_ClockSelect = UART_CS_PCLK;
} else {
m_ClockSelect = UART_CS_EPLLCLK;
}
dwBit |= (m_ClockSelect);
m_pReg6410Uart->Write_UCON(dwBit);
}
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();
}
#ifdef USE_DMA
BOOL CPdd6410Uart::InitXmitDMA(void)
{
UINT UART_TXH = 0;
UART_TXH = S3C6410_BASE_REG_PA_UART0 + (m_dwDevIndex*S3C6410_BASE_REG_OFFSET_UART)+0x20;
DMA_initialize_channel(&g_OutputDMA, TRUE);
if(DMA_set_channel_destination(&g_OutputDMA, UART_TXH, BYTE_UNIT, BURST_1, FIXED))
{
return FALSE;
}
return TRUE;
}
BOOL CPdd6410Uart::EnableTxDMA(BOOL fEnable)
{
RETAILMSG(UART_DMA_MSG, (TEXT("CPddS3CXUart::EnableDMA(%d)\r\n"), fEnable));
m_HardwareLock.Lock();
DWORD dwBit = m_pReg6410Uart->Read_UCON();
if (fEnable)
{
// for UART1 - DMA1
dwBit &= ~(3<<2);
dwBit |= (2<<2);
}
else
{
// Set Interrupt Tx Mode.
dwBit &= ~(3<<2);
dwBit |= (1<<2);
}
m_pReg6410Uart->Write_UCON(dwBit );
//
dwBit = m_pReg6410Uart->Read_UFCON();
if (fEnable)
{
dwBit &= ~(3<<6);//8
}
else
{
// Set Trigger level to 16.
dwBit &= ~(3<<6);//empty
dwBit |= (UART_FCR_TX_FIFO_TRIG_16);//16
}
m_pReg6410Uart->Write_UFCON(dwBit );
m_HardwareLock.Unlock();
return TRUE;
}
BOOL CPdd6410Uart::StopXmitDMA(void)
{
BOOL ret = FALSE;
// UARTMSG(0, (TEXT("StopXmitDMA\r\n")));
DMA_channel_stop(&g_OutputDMA);
return ret;
}
BOOL CPdd6410Uart::StartXmitDMA(PUCHAR pTxBuffer, ULONG BuffLen)
{
DWORD dwDmaLen = BuffLen;
DMA_ERROR dma_error_value = DMA_SUCCESS;
ULONG WaitReturn;
DWORD interrupts=0;
UINT UART_TXH = 0;
UART_TXH = S3C6410_BASE_REG_PA_UART0 + (m_dwDevIndex*S3C6410_BASE_REG_OFFSET_UART)+0x20;
RETAILMSG(UART_DMA_MSG,(TEXT("[UART] +StartXmitDMA (%d) \r\n"),dwDmaLen));
EnableTxDMA(TRUE);
memcpy(pVirtDmaSrcBufferAddr,pTxBuffer,dwDmaLen);
DMA_set_channel_source(&g_OutputDMA, (UINT)DmaSrcAddress, BYTE_UNIT, BURST_1, INCREASE);
DMA_set_channel_destination(&g_OutputDMA, (UINT)UART1_TX_DATA_PHY_ADDR, BYTE_UNIT, BURST_1, FIXED);
DMA_set_channel_transfer_size(&g_OutputDMA, dwDmaLen);
DMA_channel_start(&g_OutputDMA);
WaitReturn = WaitForSingleObject(pPublicUart->hTxDmaDoneDoneEvent, WRITE_TIME_OUT_CONSTANT);
DMA_channel_stop(&g_OutputDMA);
if ( WAIT_TIMEOUT == WaitReturn )
{
// Timeout
RETAILMSG (1, (TEXT("[UART] TX DMA timeout!!!\r\n")));
RETAILMSG (1, (TEXT("[UART] LEN:%d, TX:%d\r\n"), dwDmaLen, m_pReg6410Uart->Read_UFSTAT()>>8));
return FALSE;
}
EnableTxDMA(FALSE);
RETAILMSG(UART_DMA_MSG,(TEXT("[UART] -StartXmitDMA\r\n")));
return TRUE;
}
#endif //USE_DMA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -