📄 serialhw.c
字号:
//
// This function initializes serial device head.
//
// Parameters:
// bIR
// [in] Is IR mode enabled.
// bType
// [in] Serial device type (DCE/DTE).
// HWAddress
// [in] UART physical base adress.
// pRegBase
// [in] Pointer UART base adress.
// pContext
// [in] Pointer to device head.
// EventCallback
// [in] This callback exists in MDD.
// pMDDContext
// [in] This is the first parm to callback.
// pBaudTable
// [in] BaudRate Table.
//
// Returns:
// TRUE if success. FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL SL_Init( BOOL bIR, uartType_c bType, ULONG HWAddress, PUCHAR pRegBase,
PVOID pContext, EVENT_FUNC EventCallback,
PVOID pMDDContext, PLOOKUP_TBL pBaudTable )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
BOOL Ret = TRUE;
ULONG bRefFreq = UART_REF_FREQ;
UCHAR bDIV = 0;
DEBUGMSG(ZONE_INIT,(TEXT("SL_INIT+ \r\n")));
pHWHead->UseIrDA = bIR;
pHWHead->UartType = bType;
pHWHead->pUartReg = (PCSP_UART_REG)pRegBase;
pHWHead->HwAddr = HWAddress;
// Store info for callback function
pHWHead->EventCallback = EventCallback;
pHWHead->pMDDContext = pMDDContext;
// Now set up remaining fields
if (pBaudTable != NULL)
pHWHead->pBaudTable = (LOOKUP_TBL *) pBaudTable;
else
return FALSE;
if (!BSPUartEnableClock(pHWHead->HwAddr, TRUE))
{
DEBUGMSG(ZONE_ERROR, (TEXT("SL_Init: BSPUartEnableClock failed!\r\n")));
return FALSE;
}
pHWHead->FlushDone = CreateEvent(0, FALSE, FALSE, NULL);
pHWHead->ulDiscard = 0;
InitializeCriticalSection(&(pHWHead->TransmitCritSec));
InitializeCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG(ZONE_INIT,(TEXT("SL_INIT-\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: SL_Deinit
//
// This function frees any memory allocated.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_Deinit( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
DEBUGMSG(ZONE_INIT,(TEXT("SL_Deinit+\r\n")));
//Clear DTR
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_DSR) );
if (pHWHead->UartType == DCE)
{
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_DCD) );
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_RI) );
}
if (!pHWHead->UseIrDA) {
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_DTRDEN) );
}
OUTREG32( &pHWHead->pUartReg->UCR1, INREG32(&pHWHead->pUartReg->UCR1)&~CSP_BITFMASK(UART_UCR1_UARTEN) );
if (pHWHead->FlushDone) {
CloseHandle(pHWHead->FlushDone);
pHWHead->FlushDone = NULL;
}
// delete the critical section
DeleteCriticalSection(&(pHWHead->TransmitCritSec));
DeleteCriticalSection(&(pHWHead->RegCritSec));
//Disable UART Clock
BSPUartEnableClock(pHWHead->HwAddr, FALSE);
DEBUGMSG(ZONE_INIT,(TEXT("SL_Deinit-\r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_Open
//
// This function is called by the upper layer to
// open the serial device.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_Open( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
PSER_INFO pSerHead = (PSER_INFO)pContext;
ULONG bRefFreq = UART_REF_FREQ;
UCHAR bDIV = 0;
int i;
DEBUGMSG(ZONE_OPEN, (TEXT("SL_Open+ \r\n")));
SL_ClearPendingInts(pHWHead);
pHWHead->DroppedBytes = 0;
pHWHead->CTSFlowOff = FALSE; // Not flowed off yet
pHWHead->DSRFlowOff = FALSE; // Not flowed off yet
pHWHead->CommErrors = 0;
pHWHead->ModemStatus = 0;
//initialize as logic 0:high
pHWHead->bDSR = TRUE;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
DEBUGMSG(ZONE_OPEN, (TEXT("SL_Open Setting DCB parameters\r\n")));
// Reset UART
OUTREG32(&pHWHead->pUartReg->UCR2,CSP_BITFVAL(UART_UCR2_SRST, UART_UCR2_SRST_RESET));
// Wait until UART comes out of reset
while (!(INREG32(&pHWHead->pUartReg->UCR2) & CSP_BITFMASK(UART_UCR2_SRST)));
OUTREG32(&pHWHead->pUartReg->UCR1, CSP_BITFVAL(UART_UCR1_UARTEN, UART_UCR1_UARTEN_ENABLE) |//Enable UART
CSP_BITFVAL(UART_UCR1_ICD, UART_UCR1_ICD_8FRAMES)); //idle condition detect
OUTREG32(&pHWHead->pUartReg->UCR2, CSP_BITFVAL(UART_UCR2_SRST, UART_UCR2_SRST_NORESET) | //no reset
CSP_BITFVAL(UART_UCR2_WS, UART_UCR2_WS_8BIT)); //8 Bits
OUTREG32(&pHWHead->pUartReg->UCR3, CSP_BITFVAL(UART_UCR3_RXDMUXSEL, UART_UCR3_RXDMUXSEL_MUX));
OUTREG32(&pHWHead->pUartReg->UCR4, CSP_BITFVAL(UART_UCR4_CTSTL, UART_RXFIFO_DEPTH/2));
bDIV = SL_CalculateRFDIV(&bRefFreq);
OUTREG32(&pHWHead->pUartReg->UFCR, CSP_BITFVAL(UART_UFCR_RXTL, SER_FIFO_RXTL) |
CSP_BITFVAL(UART_UFCR_TXTL, SER_FIFO_TXTL) |
CSP_BITFVAL(UART_UFCR_RFDIV, bDIV));
pHWHead->pUartReg->ONEMS = (UINT16)(bRefFreq/1000);
if (pHWHead->UartType == DTE)
OUTREG32(&pHWHead->pUartReg->UFCR, INREG32(&pHWHead->pUartReg->UFCR)|CSP_BITFVAL(UART_UFCR_DCEDTE, UART_UFCR_DCEDTE_DTE)); // Configure as DTE
// Get defaults from the DCB structure
SL_SetByteSize(pContext, pHWHead->dcb.ByteSize);
SL_SetStopBits(pContext, pHWHead->dcb.StopBits);
SL_SetParity(pContext, pHWHead->dcb.Parity);
SL_SetBaudRate(pContext, pHWHead->dcb.BaudRate);
//Enable Transmiter & Receiver
INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_TXEN, UART_UCR2_TXEN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_RXEN, UART_UCR2_RXEN_ENABLE);
//Ignore RTS
OUTREG32(&pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)| CSP_BITFVAL(UART_UCR2_IRTS, UART_UCR2_IRTS_IGNORERTS));
//Set CTS
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_CTSC) );
SL_ClearPendingInts( pHWHead );
//Enable Aging timer interrupt in non-DMA mode.
if (pSerHead->useDMA == FALSE)
INSREG32BF(&pHWHead->pUartReg->UCR2, UART_UCR2_ATEN, UART_UCR2_ATEN_ENABLE);
else
// Enable Aging timeout DMA request
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_ATDMAEN, 1);
//Enable Parity Error Interrupt;
//Enable Frame Error interrupt;
INSREG32BF(&pHWHead->pUartReg->UCR3, UART_UCR3_PARERREN, UART_UCR3_PARERREN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR3, UART_UCR3_FRAERREN, UART_UCR3_FRAERREN_ENABLE);
//Enable Break Condition Detected Interrupt;
//Enable Overrun interrupt;
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_BKEN, UART_UCR4_BKEN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_OREN, UART_UCR4_OREN_ENABLE);
//Enable Receiver Data Ready Interrupt in non-DMA mode;
if (pSerHead->useDMA == FALSE)
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_DREN, UART_UCR4_DREN_ENABLE);
if (pHWHead->UseIrDA) {
//Enable IR interrupt
INSREG32BF(&pHWHead->pUartReg->UCR4, UART_UCR4_ENIRI, UART_UCR4_ENIRI_ENABLE);
}
else {
//Enable CTS state change Interrupt;
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_RTSDEN, UART_UCR1_RTSDEN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR3, UART_UCR3_DTRDEN, UART_UCR3_DTRDEN_ENABLE);
}
if (pHWHead->UseIrDA) {
BSPIrdaEnable(TRUE);
BSPIrdaSetMode(SIR_MODE);
}
if (pSerHead->useDMA)
{
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_RDMAEN, UART_UCR1_RXDMAEN_ENABLE);
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_TDMAEN, UART_UCR1_TXDMAEN_ENABLE);
if (!BSPSerAcquireDMAReqGpr(pSerHead->dwIOBase))
DEBUGMSG(ZONE_OPEN, (TEXT("BSPSerAcquireDMAReqGpr failed\n")));
// Initialize the chain and set the watermark level
if (!DDKSdmaInitChain(pSerHead->SerialDmaChanRx, SER_FIFO_RXTL ))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Rx): DDKSdmaInitChain failed.\r\n")));
goto cleanUp;
}
DDKSdmaClearChainStatus(pSerHead->SerialDmaChanRx);
for (i = 0; i < SERIAL_MAX_DESC_COUNT_RX; i++)
{
UINT32 Mode;
Mode = (i == (SERIAL_MAX_DESC_COUNT_RX - 1)) ? DDK_DMA_FLAGS_WRAP : DDK_DMA_FLAGS_CONT;
DDKSdmaSetBufDesc(pSerHead->SerialDmaChanRx,
i,
(DDK_DMA_FLAGS_INTR | Mode),
(pSerHead->SerialPhysRxDMABufferAddr.LowPart) + i * pSerHead->rxDMABufSize,
0,
DDK_DMA_ACCESS_8BIT,
pSerHead->rxDMABufSize);
}
pSerHead->currRxDmaBufId = 0;
pSerHead->dmaRxStartIdx = 0;
pSerHead->availRxByteCount = 0;
DDKSdmaStartChan(pSerHead->SerialDmaChanRx);
// Initialize the chain and set the watermark level
if (!DDKSdmaInitChain(pSerHead->SerialDmaChanTx, SER_FIFO_TXTL))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Tx): DDKSdmaInitChain failed.\r\n")));
goto cleanUp;
}
DDKSdmaClearChainStatus(pSerHead->SerialDmaChanTx);
pSerHead->dmaBufFirstUseBmp = (1 << SERIAL_MAX_DESC_COUNT_TX) - 1;
pSerHead->currTxDmaBufId = 0;
cleanUp:
;
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG(ZONE_OPEN, (TEXT("SL_Open- \r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_Close
//
// This function closes the device initialized
// by the SL_Init function.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_Close( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
DEBUGMSG(ZONE_CLOSE,(TEXT("SL_Close+ \r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
// Disable extern IrDa pin
if (pHWHead->UseIrDA) {
BSPIrdaEnable(FALSE);
}
if (pHWHead->UseIrDA)
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_ENIRI) );
else
OUTREG32( &pHWHead->pUartReg->UCR1, INREG32(&pHWHead->pUartReg->UCR1)&~CSP_BITFMASK(UART_UCR1_RTSDEN) );
//Disable Receiver Data Ready Interrupt;
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_DREN) );
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_TCEN) );
//Disable Break Condition Detected Interrupt;
//Disable Overrun interrupt;
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_BKEN) );
OUTREG32( &pHWHead->pUartReg->UCR4, INREG32(&pHWHead->pUartReg->UCR4)&~CSP_BITFMASK(UART_UCR4_OREN) );
//Disable Parity Error Interrupt;
//Disable Frame Error interrupt;
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_PARERREN) );
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_FRAERREN) );
//Disable Aging timer interrupt
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_ATEN) );
//Clear RTS
OUTREG32( &pHWHead->pUartReg->UCR2, INREG32(&pHWHead->pUartReg->UCR2)&~CSP_BITFMASK(UART_UCR2_CTS) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -