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

📄 ser_arch.c

📁 基于三星S3C2410的串口驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
						break;
					default:
						bRet = FALSE;
						break;
					}
					if (bRet)
						OUTREG(pInfoSerArch,rULCON,lcr) ;
				}
			}
			//StopBits
			if( dwFlagSetDCB & SETDCB_STOPBITS )
			{
				UINT32 lcr;
				bRet = TRUE;
				//if( StopBits==TWOSTOPBITS || StopBits==ONESTOPBIT )
				//WRITE_BITFIELD(struct utcr0Bits, &pUART->utcr0, sbs, (lpDCB->StopBits==TWOSTOPBITS ? 1 : 0));
				{
					lcr = INREG(pInfoSerArch,rULCON);
					lcr &= ~SER2410_STOPBIT_MASK;	//0x4
					
					switch ( lpDCB->StopBits ) 
					{
					case ONESTOPBIT :
						lcr |= 0;//SERIAL_1_STOP ;
						break;
					case ONE5STOPBITS :
						//lcr |= SERIAL_1_5_STOP ;
						//break;
					case TWOSTOPBITS :
						lcr |= 4;//SERIAL_2_STOP ;
						break;
					default:
						bRet = FALSE;
						break;
					}
					if (bRet)
						OUTREG(pInfoSerArch,rULCON,lcr);
				}
			}
			//LeaveCriticalSection(&(pInfoSerArch->RegCritSec));
			//RETAILMSG( 1, (TEXT( "\r\nser_SetBaud: baud=%d, pUart=0x[%x]\r\n" ), lpDCB->BaudRate, pUART));

			//判断并设置硬件信号---disable, enable, or nothing
			//if( pInfoSerArch->dwOpt & OPT_MODEM )
			{
				if ( lpDCB->fDtrControl == DTR_CONTROL_DISABLE ) 
					SerArch_ClearPinDTR( pInfoSerArch );
				else if ( lpDCB->fDtrControl == DTR_CONTROL_ENABLE ) 
					SerArch_SetPinDTR( pInfoSerArch );
				if ( lpDCB->fRtsControl == RTS_CONTROL_DISABLE ) 
					SerArch_ClearPinRTS( pInfoSerArch );
				else if ( lpDCB->fRtsControl == RTS_CONTROL_ENABLE ) 
					SerArch_SetPinRTS( pInfoSerArch );
			}
			//dcb_Debug( lpDCB, "SerArch_SetDCB" );
		}
		else
		{
			return FALSE;
		}
	}

	return TRUE;
}

//-----------------------------------------
// ********************************************************************
// 声明:ULONG	SerArch_GetComStat(PVOID pHead, LPCOMSTAT lpStat)
// 参数:
//	IN pHead-ARCH信息
//	OUT lpStat-保存状态
// 返回值:
//	返回错误信息
// 功能描述:获取MODEM状态
// 引用: 
// ********************************************************************
ULONG	SerArch_GetComStat(PVOID pHead, LPCOMSTAT lpStat)
{
	PSERARCH_INFO	pInfoSerArch = (PSERARCH_INFO)pHead;
	ULONG			RetVal;
	
	RetVal = pInfoSerArch->CommErrors;
	pInfoSerArch->CommErrors = 0;//Clear old errors each time
	//
	if (lpStat)
	{
		lpStat->fDsrHold  = pInfoSerArch->FlowOffDSR;
		lpStat->fCtsHold  = pInfoSerArch->FlowOffCTS;
		//pInfoSerArch->CommStat = 0;
		//pInfoSerArch->CommStat.fEof = 0;
	}
	return RetVal;
}
// ********************************************************************
// 声明:VOID	SerArch_GetCommProperties(PVOID pHead,LPCOMMPROP pCommProp)
// 参数:
//	IN pHead-ARCH信息
//	OUT pCommProp-保存属性信息
// 返回值:
//	无
// 功能描述:获取属性信息
// 引用: 
// ********************************************************************
VOID	SerArch_GetCommProperties(PVOID pHead,LPCOMMPROP pCommProp)
{
	*pCommProp = ((PSERARCH_INFO)pHead)->CommProp;
}
// ********************************************************************
// 声明:VOID SerArch_GetModemStatus(PVOID pHead, LPDWORD pModemStatus)
// 参数:
//	IN pHead-ARCH信息
//	OUT pModemStatus-保存modem状态信息
// 返回值:
//	无
// 功能描述:获取modem状态信息
// 引用: 
// ********************************************************************
VOID SerArch_GetModemStatus(PVOID pHead, LPDWORD pModemStatus)
{
	PSERARCH_INFO	pInfoSerArch = (PSERARCH_INFO)pHead;

	//if( pInfoSerArch->dwOpt & OPT_MODEM )
	{
		pInfoSerArch->ModemStatus = ser_ReadMSR( pInfoSerArch );
	}
	*pModemStatus = pInfoSerArch->ModemStatus;
	//EdbgOutputDebugString( "mState=%x, *pModemStatus=%x\r\n", ((PSERARCH_INFO)pHead)->ModemStatus, *pModemStatus );
}
// ********************************************************************
// 声明:BOOL	SerArch_XMitChar(PVOID pHead, UCHAR ComChar)
// 参数:
//	IN pHead-ARCH信息
//	IN ComChar-待发送的字符
// 返回值:
//	无
// 功能描述:立即发送1个字符
// 引用: 
// ********************************************************************
BOOL	SerArch_XMitChar(PVOID pHead, UCHAR ComChar)
{
	PSERARCH_INFO pInfoSerArch = (PSERARCH_INFO)pHead;
	volatile PS2410_UART_REG pUART;
	ULONG       rFifoStat, TxFifoCnt;

	//pUART = pInfoSerArch->pUART;
    EnterCriticalSection(&(pInfoSerArch->csTransmit));
	while( 1 )
	{
		//EnterCriticalSection(&(pInfoSerArch->RegCritSec));
		// Write the character if we can
		rFifoStat = INREG(pInfoSerArch,rUFSTAT);
		TxFifoCnt = (rFifoStat & SER2410_FIFOCNT_MASK_TX) >> 4;
		
		if (!(rFifoStat & SER2410_FIFOFULL_TX) && (TxFifoCnt < (SER2410_FIFO_DEPTH_TX-1))) 
		{
			// FIFO is empty, send this character
			//OUTB(pInfoSerArch, pData, ComChar);
			OUTREG(pInfoSerArch,rUTXH,ComChar);	// 传输寄存器
			// Make sure we release the register critical section
			//LeaveCriticalSection(&(pInfoSerArch->RegCritSec));
			break;
		}
		
		// If we couldn't write the data yet, then wait for a
		// TXINTR to come in and try it again.
		
		// Enable xmit intr.
		//EnINT(pInfoSerArch, pInfoSerArch->bINT);
		//EnSubINT(pInfoSerArch, pInfoSerArch->bTxINT | pInfoSerArch->bRxINT | pInfoSerArch->bErrINT); // canceled 
		EnSubINT(pInfoSerArch, pInfoSerArch->bTxINT);
		pInfoSerArch->fSW_EnTxINT = TRUE;
		//LeaveCriticalSection(&(pInfoSerArch->RegCritSec));
		
		// Wait until the txintr has signalled.
		
		WaitForSingleObject(pInfoSerArch->hEvtXMit, (ULONG)1000);
#if 0
		if( pUART->utsr1.tnf )
		{
			(pUART->utdr.data) = ComChar;

			//pInfoSerArch->CommErrors &= ~CE_TXFULL;
			//pInfoSerArch->CommStat.fTxim = 0;
			break;
		}
		else
		{
			//struct utsr0Bits utsr0;
			//ULONG	time;
			
			//检查硬件
			//utsr0 = pUART->utsr0;
			//if( (utsr0.eif) || (utsr0.rbb) || (utsr0.reb) )
			//{
			//	ser_CheckLine( pInfoSerArch, pUART );
			//}
			//pInfoSerArch->CommErrors |= CE_TXFULL;
			//pInfoSerArch->CommStat.fTxim = 1;

			WRITE_BITFIELD(struct utcr3Bits,&pUART->utcr3,tie,1);
			//EdbgOutputDebugString( "wait for xmit char\r\n" );
			WaitForSingleObject( pInfoSerArch->hEvtXMit, 400 );
			//time = 0;
			//while( !pInfoSerArch->fWaitTxim )//by xyg
			//{
			//	usWait( 1 );
			//	time ++;
			//	if( time>400000 )//1s timeout
			//		break;
			//}
			//pInfoSerArch->fWaitTxim = 0;
		}
#endif
	}
	LeaveCriticalSection(&(pInfoSerArch->csTransmit));

	return(TRUE);
}

//------------------------------------------------------------------------------
// ********************************************************************
// 声明:DWORD	SerArch_IntrTypeQuery(PVOID pHead)
// 参数:
//	IN pHead-ARCH信息
// 返回值:
//	无
// 功能描述:查询中断类型
// 引用: 
// ********************************************************************
DWORD	SerArch_IntrTypeQuery(PVOID pHead)
{
    PSERARCH_INFO	pInfoSerArch = (PSERARCH_INFO)pHead;
    DWORD			interrupts	= INTR_NONE;
	ULONG IntSubPndVal;//=0;

//	RETAILMSG(1,(TEXT("\r\n Ser_Query \r\n")));
	IntSubPndVal  = *(pInfoSerArch->UART_INTSUBSRCPND);
	//查询 出错状态---溢出 | 奇偶 | 帧] 错误
	if(IntSubPndVal & (pInfoSerArch->bErrINT) )
	{
		interrupts = INTR_LINE;  // Error status
	}
	else
	{
		//查询 接收状态
#ifndef CANCEL_XYG_SER_RX
		if( pInfoSerArch->lpRWBuf->dwCntRW )
		{
			interrupts = INTR_RX;    // Received valid data.
		}
#else

#if 1
		ULONG       rFifoStat;
		rFifoStat = INREG(pInfoSerArch,rUFSTAT);
		if( ((rFifoStat & 0x0f) > 0) || (rFifoStat & 0x100) )
		{
			interrupts = INTR_RX;    // Received valid data.
		}
#else
		if(IntSubPndVal & (pInfoSerArch->bRxINT) )
		{
			//RETAILMSG(1,(TEXT("SerArch_IntrTypeQuery:RxINT\n")));
			//RETAILMSG(1,(TEXT("\r\n Ser_Query rx \r\n")));
			interrupts = INTR_RX;    // Received valid data.
		}
#endif
#endif
		//查询 发送状态
		else if((IntSubPndVal & (pInfoSerArch->bTxINT)) && pInfoSerArch->fSW_EnTxINT )
		{
			//RETAILMSG(1,(TEXT("SerArch_IntrTypeQuery:TxINT\n")));
			interrupts |= INTR_TX;	// Tx.
		}
	}

	//查询 是否由于硬件握手 要求继续发送
	if( pInfoSerArch->RestartTxForFlow )
    {
        interrupts |= INTR_TX;
		pInfoSerArch->RestartTxForFlow = 0;
    }

	//查询 MODEM状态
	//if( pInfoSerArch->dwOpt & OPT_MODEM )
    if( interrupts & INTR_TX )
	{
		ULONG       msr_val;
		volatile	WORD	msr_ret;
		WORD	msrChange;
		
		//读硬件
		msr_ret = MS_DSR_ON;
		msr_val = INREG(pInfoSerArch,rUMSTAT);
		if (msr_val & COM2410_MSR_CTS)
		{
			msr_ret |= MS_CTS_ON;
		}
		//msr_ret = ser_ReadMSR( pInfoSerArch );
		//
		if( msrChange = (pInfoSerArch->ModemStatus ^ msr_ret) )
		{
			//保存状态
			pInfoSerArch->ModemStatus = msr_ret;
			pInfoSerArch->msrChange = msrChange;

			interrupts |= INTR_MODEM;
		}
	}
	
	//查询 OSM2中断状态
//	irq |= HW_SA11x0GetOSM2( pHead );

    return(interrupts);
}

// ********************************************************************
// 声明:VOID SerArch_IntrHandleTx(PVOID pHead)
// 参数:
//	IN pHead-ARCH信息
// 返回值:
//	无
// 功能描述:处理发送中断
// 引用: 
// ********************************************************************
VOID SerArch_IntrHandleTx(PVOID pHead)
{
	PSERARCH_INFO   pInfoSerArch  = (PSERARCH_INFO)pHead;

	//////EdbgOutputDebugString("SerArch_IntrHandleTxHandler: set tie=0, only do this");
	EnterCriticalSection(&(pInfoSerArch->csTransmit));
	//EnterCriticalSection(&(pInfoSerArch->RegCritSec));

	//停止 发送中断
	//DisEnINT(pInfoSerArch, pInfoSerArch->bINT);
	DisEnSubINT(pInfoSerArch, pInfoSerArch->bTxINT);
	pInfoSerArch->fSW_EnTxINT = FALSE;
	//清除Pending串口中断
	ClearSubINTPnd(pInfoSerArch, pInfoSerArch->bTxINT );
	ClearINTPnd(pInfoSerArch, pInfoSerArch->bINT);
	//if ((*pInfoSerArch->UART_INTPND) & pInfoSerArch->bINT )
	//{
	//	(*pInfoSerArch->UART_INTPND)		|= pInfoSerArch->bINT;
	//}

	//LeaveCriticalSection(&(pInfoSerArch->RegCritSec));
	LeaveCriticalSection(&(pInfoSerArch->csTransmit));
}

// ********************************************************************
// 声明:VOID	SerArch_IntrHandleLine(PVOID pHead)
// 参数:
//	IN pHead-ARCH信息
// 返回值:
//	无
// 功能描述:处理状态中断
// 引用: 
// ********************************************************************
VOID	SerArch_IntrHandleLine(PVOID pHead)
{
	PSERARCH_INFO   pInfoSerArch  = (PSERARCH_INFO)pHead;

	//EdbgOutputDebugString("INTR_LINE\r\n");
	//检查硬件
	ser_CheckLine( pInfoSerArch, pInfoSerArch->pUART );
}

// ********************************************************************
// 声明:DWORD	SerArch_IntrHandleModem( PVOID pHead )
// 参数:
//	IN pHead-ARCH信息
// 返回值:
//	无
// 功能描述:处理MODEM中断
// 引用: 
// ********************************************************************
DWORD	SerArch_IntrHandleModem( PVOID pHead )
{
	PSERARCH_INFO	pInfoSerArch = (PSERARCH_INFO)pHead;
	BOOL			fFlowChangeToOn = FALSE;

	//分析是否改变
	if(	pInfoSerArch->dwOpenCount )
	{
		DWORD	dwMdmEvt;
		WORD	msrChange;
		
		dwMdmEvt = 0;
		msrChange = pInfoSerArch->msrChange;
		if( msrChange & MS_CTS_ON )
			dwMdmEvt |= EV_CTS;
		if( msrChange & MS_DSR_ON )	//MS_RLSD_ON
		{
			dwMdmEvt |= EV_DSR;
			dwMdmEvt |= EV_RLSD;
		}
		//状态  发生改变
		if( dwMdmEvt )
			pInfoSerArch->lpfnEventNotify( pInfoSerArch->pHeadDrv, dwMdmEvt );

		//恢复
		if( pInfoSerArch->FlowOffDSR && (pInfoSerArch->ModemStatus & MS_DSR_ON) )
		{
			pInfoSerArch->FlowOffDSR = 0;
			fFlowChangeToOn = TRUE;
		}
		if( pInfoSerArch->FlowOffCTS && (pInfoSerArch->ModemStatus & MS_CTS_ON) )
		{
			pInfoSerArch->FlowOffCTS = 0;
			fFlowChangeToOn = TRUE;
		}
		if( fFlowChangeToOn )
		{
			//EdbgOutputDebugString( "Modem Intr Handler: set tie=1\r\n" );
			//WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,tie,1);
			//EnINT(pInfoSerArch, pInfoSerArch->bINT);
			//EnSubINT(pInfoSerArch, pInfoSerArch->bTxINT | pInfoSerArch->bRxINT | pInfoSerArch->bErrINT);
			EnSubINT(pInfoSerArch, pInfoSerArch->bTxINT);

⌨️ 快捷键说明

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