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

📄 ser_arch.c

📁 基于三星S3C2410的串口驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/


/*****************************************************
文件说明:串口驱动---硬件相关层
版本号:  1.0.0
开发时期:2003-07-01
作者:    肖远钢
修改记录:
2004-03-18:凡是带有这个标记的,跟不同板子的调试串口 是相关的
******************************************************/

//root include
#include <ewindows.h>

//arm\ebook_  include
#include <s2410.h>
#include <oalintr.H>
#include <serbaud.h>	//add by xyg
//driver  include
#include <sertbl.h>		//add by xyg
//current

//added by xyg 2004-09-28
//#include "ser_rwbuf.h"
#include "drv_glob.h"
#include "ser_arch.h"	//add by xyg
#ifndef CANCEL_XYG_SER_RX
static DRIVER_GLOBALS * lpGlobal =(DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START;
#endif


/***************  全局区 定义, 声明 *****************/


//-----------------------------------------
//调试部分的定义
//-----------------------------------------

//
//#define	DEBUG_SERARCH	// 

//#define xyg_ser_sub_mask

//
#ifdef	DEBUG_SERARCH

//
static	PSERARCH_INFO	g_pDebugSerArch = NULL;

//调试函数
#define	DEBUGTO_NONE		0
#define	DEBUGTO_SERIAL		1
#define	DEBUGTO_DESKTOP		2
extern	DWORD	SerDebug_Enable( DWORD dwFlag );
extern	void	SerDebug_CleanScreen( );
extern	void	OEM_WriteDebugByte_ToWnd(unsigned char c);

extern	void	dcb_Debug( LPDCB lpDCB, LPTSTR pszText );
static	void	Debug_Arch( PVOID pHead );

#endif

//-----------------------------------------
//正常的定义
//-----------------------------------------

#define		UART_DEBUGPORT		UART3_BASE_VIRTUAL

//-----------------------------------------
extern	void	msWait(unsigned msVal);
extern	void	usWait(unsigned usVal);
extern	void	ser_NotifyCommEvent(PVOID pHead, ULONG fdwEventMask);
extern	void	ser_HandleInterrupt( LPVOID pData );

//-----------------------------------------
//wait interrupt
static	DWORD	WINAPI	ser_WaitInterrupt( DWORD  pHead );
static	void	Debug_Arch( PVOID pHead );
//help fun
static	BOOL	ser_InitInfoOfHardware( PSERARCH_INFO pInfoSerArch, ULONG Identifier );
static	void	ser_CheckLine(PSERARCH_INFO pInfoSerArch, volatile PS2410_UART_REG pUART);
static	void	ser_OpenMode( PSERARCH_INFO pInfoSerArch );
static	void	ser_CloseMode( PSERARCH_INFO pInfoSerArch );
static	BOOL	ser_CheckDCB( LPDCB lpDCB, PSERARCH_INFO pInfoSerArch );
static	BOOL	ser_CheckFlowOff( PSERARCH_INFO pInfoSerArch );

//init, deinit
static	PVOID	SerArch_Init( ULONG Identifier, PVOID pHeadDrv, PVOID lpDCB );
static	VOID	SerArch_InitLast( PVOID   pHead );
static	BOOL	SerArch_Deinit( PVOID   pHead );
static	ULONG	SerArch_Close( PVOID   pHead );
static	BOOL	SerArch_Open( PVOID pHead );
static	BOOL	SerArch_PowerOff(PVOID pHead);
static	BOOL	SerArch_PowerOn(PVOID pHead);
static	BOOL	SerArch_IOControl(PVOID pHead, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);
//
static	BOOL	SerArch_IREnable(PVOID pHead,ULONG BaudRate);
static	BOOL	SerArch_IRDisable(PVOID pHead);
//
static	ULONG	SerArch_Recv( PVOID pHead, LPBYTE pBufDes, LONG* pnLenBuf );
static	ULONG	SerArch_Send( PVOID pHead, LPBYTE pBufSrc, LONG* pnLenBuf );
static	BOOL	SerArch_XMitChar(PVOID pHead, UCHAR ComChar);
//
static	DWORD	SerArch_IntrTypeQuery( PVOID pHead );
static	DWORD	SerArch_IntrHandleModem(PVOID pHead);
static	VOID	SerArch_IntrHandleLine(PVOID pHead);
static	VOID	SerArch_IntrHandleTx(PVOID pHead);
//
static	VOID	SerArch_ClearPinDTR( PVOID pHead );
static	VOID	SerArch_SetPinDTR( PVOID pHead );
static	VOID	SerArch_ClearPinRTS( PVOID pHead );
static	VOID	SerArch_SetPinRTS( PVOID pHead );
//
static	VOID	SerArch_ClearBreak( PVOID pHead );
static	VOID	SerArch_SetBreak( PVOID pHead );
//
static	VOID	SerArch_PurgeComm(PVOID pHead,DWORD fdwAction);
//
static	ULONG	SerArch_GetComStat(PVOID pHead, LPCOMSTAT lpStat);
static	VOID	SerArch_GetCommProperties(PVOID pHead,LPCOMMPROP pCommProp);
static	VOID	SerArch_GetModemStatus(PVOID pHead, LPDWORD pModemStatus);
static	BOOL	SerArch_SetDCB( PVOID pHead, LPDCB lpDCB, DWORD dwFlagSetDCB );

//-----------------------------------------
//inline function
static	WORD	ser_ReadMSR( PSERARCH_INFO pInfoSerArch );

#if defined( HW_PCB_VERSION_C )
static	void	ser_SelectSIR( PSERARCH_INFO pInfoSerArch );
#endif

/******************************************************/

//-----------------------------------------
// ********************************************************************
// 声明:WORD	ser_ReadMSR( PSERARCH_INFO pInfoSerArch )
// 参数:
//	IN pGPIO-GPIO的地址
// 返回值:
//	返回MODEM的状态
// 功能描述:读取MODEM的状态
// 引用: 
// ********************************************************************
WORD	ser_ReadMSR( PSERARCH_INFO pInfoSerArch )
{
	volatile	WORD	msr_ret;
	ULONG       msr_val;
	
	//读硬件
	//msr_ret = 0;
	//if( !pGPIO->gplr.gp14 )
	//{
	//	msr_ret |= MS_CTS_ON;
	//}
	//if( !pGPIO->gplr.gp13 )
	//{
	//	msr_ret |= MS_DSR_ON;
	//	msr_ret |= MS_RLSD_ON;
	//}
	msr_ret = MS_DSR_ON;
	msr_val = INREG(pInfoSerArch,rUMSTAT);
	if (msr_val & COM2410_MSR_CTS)
	{
		msr_ret |= MS_CTS_ON;
	}

	return msr_ret;
}

// ********************************************************************
// 声明:VOID ClearPendingInts( PVOID   pHead )
// 参数:
//	IN PVOID pHead - 指向PDD层的全局结构变量
// 返回值:
//	无
// 功能描述:设置寄存器,使由未知状态为已知状态
// 引用:在 SL_Init( ) 中调用
// ********************************************************************
VOID ClearPendingInts( PVOID   pHead )
{
	volatile PSERARCH_INFO   pInfoSerArch   = (PSERARCH_INFO)pHead;
	UINT32 tmpReg;

	//RETAILMSG(1,(TEXT("ClearPendingInts\n")));
	SETREG(pInfoSerArch,rUFCON,0x6);    // tx, rx fifo reset

	ClearSubINTPnd(pInfoSerArch, pInfoSerArch->bTxINT | pInfoSerArch->bRxINT | pInfoSerArch->bErrINT);	//清除SUBSRCPND中串口的 Tx,Rx,Err中断
	//RETAILMSG(1,(TEXT("**After  ClearSubINTPnd:%x\n"),pInfoSerArch->pIrqCtrlAddr->rSUBSRCPND));
	ClearINTPnd(pInfoSerArch, pInfoSerArch->bINT);	//清除SRCPND中串口中断
	//RETAILMSG(1,(TEXT("**SRCPND:%x\n"),pInfoSerArch->UART_INTSRCPND));
	//if ((*pInfoSerArch->UART_INTPND) & pInfoSerArch->bINT )
	//{
	//	(*pInfoSerArch->UART_INTPND)		|= pInfoSerArch->bINT;	//#define   BIT_UART0       ( 0x1 << 28 )
	//}
	//RETAILMSG(1,(TEXT("pInfoSerArch->UART_INTPND --- :%x\n"),pInfoSerArch->UART_INTPND));

	tmpReg = INREG(pInfoSerArch,rUERSTAT);		//进行读之后,该位清除

}

#if defined( HW_PCB_VERSION_C )
// ********************************************************************
// 声明:void	ser_SelectSIR( PSERARCH_INFO pInfoSerArch )
// 参数:
//	IN pInfoSerArch-ARCH信息
// 返回值:
//	无
// 功能描述:选择红外功能
// 引用: 
// ********************************************************************
//Select SIR function: set param, open power, open recv and send register
void	ser_SelectSIR( PSERARCH_INFO pInfoSerArch )
{
	//设置模式
	WRITE_BITFIELD(struct hscr0Bits,&pInfoSerArch->pHSSP->hscr0,itr,0);
	WRITE_BITFIELD(struct utcr4Bits,&pInfoSerArch->pUART->utcr4,hse,1);
	WRITE_BITFIELD(struct utcr4Bits,&pInfoSerArch->pUART->utcr4,lpm,0);
	//打开电源
	pInfoSerArch->pGPIO->gpdr.gp15 = 1; // 输出 方向
	pInfoSerArch->pGPIO->gpsr.gp15 = 1; // 打开电源
	{	DWORD	iDlay;	for( iDlay=0; iDlay<0xA000; iDlay++ ) ;	}
	//打开硬件的  收
	WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,rxe,1);
	WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,txe,0);
	WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,rie,1);
	WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,tie,1);
}
#endif

//-----------------------------------------

// ********************************************************************
// 声明:void	ser_CheckLine( PSERARCH_INFO pInfoSerArch, volatile PS2410_UART_REG pUART)
// 参数:
//	IN pInfoSerArch-ARCH信息
//	IN pUART-UART的地址
// 返回值:
//	无
// 功能描述:检查串口的状态
// 引用: 
// ********************************************************************
//check line status, if error occurs, then notify and clear status
void	ser_CheckLine( PSERARCH_INFO pInfoSerArch, volatile PS2410_UART_REG pUART)
{
	ULONG LineEvents;
	ULONG LineStatus;
	int nCntTry;
	//UCHAR cCharRx;
	
	//OEM_WriteDebugByte_ToWnd( 'z' );
	//EdbgOutputDebugString("\r\ne_1: sr0=%x, sr1=%x, cr0=%x\r\n", pUART->utsr0, pUART->utsr1, pUART->utcr0 );
	//出现错误
	LineEvents = 0;
	LineStatus = 0;
	nCntTry = 0;

	//RETAILMSG(1,TEXT("\r\n SerArch_CheckLine() ---- Debug_Arch \r\n"));
	//Debug_Arch( pInfoSerArch );

    while( nCntTry++<100 )
	{
		LineStatus = pUART->rUERSTAT;//INREG(pInfoSerArch,rUERSTAT);	//取寄存器状态值
		//RETAILMSG(1,(TEXT("Line Status Register:%x"),LineStatus));
		//  判断控制状态	[溢出 | 奇偶 | 帧] 错误
		if ( LineStatus & (COM2410_LSR_OE | COM2410_LSR_PE | COM2410_LSR_FE)) 
		{
			if ( LineStatus & COM2410_LSR_OE )	//溢出错误
			{
				//When overrun error occurs, S2410 rURXH must be read.
				pInfoSerArch->CommErrors |= CE_OVERRUN;
				LineEvents |= EV_ERR;
				RETAILMSG(1,TEXT("\r\n CLine_ov"));
			}
			if ( LineStatus & COM2410_LSR_PE )	//奇偶错误
			{
				pInfoSerArch->CommErrors |= CE_RXPARITY;
				LineEvents |= EV_ERR;
				//RETAILMSG(1,TEXT("\r\n CLine_pp"));
			}
			if ( LineStatus & COM2410_LSR_FE )	//帧错误
			{
				pInfoSerArch->CommErrors |= CE_FRAME;
				LineEvents |= EV_ERR;
				//RETAILMSG(1,TEXT("\r\n CLine_fr"));
			}
			//cCharRx = *(pInfoSerArch->pUFRXH);
		}
		else
		{
			break;
		}
	}

	if ( LineStatus & COM2410_LSR_BI )	//中断错误
	{
		LineEvents |= EV_BREAK;
		pInfoSerArch->CommErrors |= CE_BREAK;
		//EdbgOutputDebugString("\r\nEV_BREAK\r\n" );
	}
	
	//EdbgOutputDebugString( ",d=%d", nDiscard );
	//EdbgOutputDebugString("\r\ne_2: sr0=%x, sr1=%x, cr0=%x\r\n", pUART->utsr0, pUART->utsr1, pUART->utcr0 );
	if( LineEvents )
	{
		//通知WaitCommEvent
		pInfoSerArch->lpfnEventNotify(pInfoSerArch->pHeadDrv, LineEvents);
	}

	//清除Pending串口中断
	ClearSubINTPnd(pInfoSerArch, pInfoSerArch->bErrINT );
	ClearINTPnd(pInfoSerArch, pInfoSerArch->bINT);
#ifdef xyg_ser_sub_mask
	//if ((*pInfoSerArch->UART_INTPND) & pInfoSerArch->bINT )
	//{
	//	(*pInfoSerArch->UART_INTPND)		|= pInfoSerArch->bINT;
	//}
	//
	EnINT(pInfoSerArch, pInfoSerArch->bINT);
	EnSubINT(pInfoSerArch, (pInfoSerArch->bRxINT|pInfoSerArch->bErrINT) );
	//EnSubINT(pInfoSerArch, (pInfoSerArch->bErrINT) );
#endif

	//RETAILMSG(1,TEXT("\r\n SerArch_CheckLine() ---- Debug_Arch OVER\r\n"));
	//Debug_Arch( pInfoSerArch );
}

// ********************************************************************
// 声明:void	ser_OpenMode( PSERARCH_INFO pInfoSerArch )
// 参数:
//	IN pInfoSerArch-ARCH信息
// 返回值:
//	无
// 功能描述:结构初始化 和 硬件初始化打开
// 引用: 
// ********************************************************************
void	ser_OpenMode( PSERARCH_INFO pInfoSerArch )
{
	volatile	PS2410_UART_REG		pUART;//UART-registers

	//初始化操作信息的变量
	pInfoSerArch->fPowerOff  = 0;
	pInfoSerArch->msrChange  = 0;
    pInfoSerArch->CommErrors = 0;
	pInfoSerArch->FlowOffDSR = 0;
	pInfoSerArch->FlowOffCTS = 0;
	pInfoSerArch->RestartTxForFlow = 0;
	//pInfoSerArch->fWaitTxim  = 0;
	//
	//if( pInfoSerArch->dwOpt & OPT_MODEM )
	{
		pInfoSerArch->ModemStatus = ser_ReadMSR( pInfoSerArch );
	}
	//else
	//{
	//	pInfoSerArch->ModemStatus = ( MS_CTS_ON | MS_DSR_ON | MS_RLSD_ON );
	//}

	//
	//硬件的参数设置和状态清除( 注意:之前已经调用了HWSetDCB )
	//
	pUART = pInfoSerArch->pUART;

	// 设置波特率
	SerArch_SetDCB( pInfoSerArch, pInfoSerArch->lpDCB, SETDCB_ALL );

	//OUTREG(pInfoSerArch,rUCON,0x2c5);	// Select Clock,Tx and Rx Interrupt Type,Transmit and Receive Mode.
	OUTREG(pInfoSerArch,rUCON,0x02c5);	// Select Clock,Tx and Rx Interrupt Type,Transmit and Receive Mode.
	OUTREG(pInfoSerArch,rUFCON,0x6);		// Reset FIFO
	//OUTREG(pInfoSerArch,rUFCON,0x41);	// FIFO enable : tx-4bytes, rx-4bytes
	OUTREG(pInfoSerArch,rUFCON,0x01);	// FIFO enable : tx-4bytes, rx-4bytes
	OUTREG(pInfoSerArch,rUMCON,0x00);	// Disable auto flow control.
	//OUTREG(pInfoSerArch,rUMCON,0x10);	// Disable auto flow control.
	OUTREG(pInfoSerArch,rULCON,0x3);		// Normal mode, N81

	RETAILMSG(1,(TEXT("\n*******************************\n")));
	RETAILMSG(1,(TEXT("**rUFCON:%x\n"),pUART->rUFCON));
	RETAILMSG(1,(TEXT("**rUCON:%x\n"),pUART->rUCON));
	RETAILMSG(1,(TEXT("\n*******************************\n")));

	// 中断有效
	EnINT(pInfoSerArch, pInfoSerArch->bINT);
	//RETAILMSG(1,(TEXT("\r\n  [%x]   \r\n"),pInfoSerArch->pIrqCtrlAddr->rINTMSK));
	//RETAILMSG(1,(TEXT("Before EnSubInt function,INTSUBMSK:%x\n"),pInfoSerArch->pIrqCtrlAddr->rINTSUBMSK));
	EnSubINT(pInfoSerArch, (pInfoSerArch->bRxINT|pInfoSerArch->bErrINT));
	//EnSubINT(pInfoSerArch, pInfoSerArch->bRxINT);
	//EnSubINT(pInfoSerArch, pInfoSerArch->bErrINT);

	ser_CheckLine( pInfoSerArch, pInfoSerArch->pUART );
	ClearPendingInts( pInfoSerArch );

#ifndef CANCEL_XYG_SER_RX
	EnterCriticalSection(&(pInfoSerArch->csBufRW));
	RWBuf_SetZero( pInfoSerArch->lpRWBuf, TRUE );
	LeaveCriticalSection(&(pInfoSerArch->csBufRW));
#endif
	return ;
}

// ********************************************************************
// 声明:VOID S2410_SetIrDAIOP( PVOID  pHead )
// 参数:
//	IN PVOID  pHead - PDD层全局结构变量
// 返回值:
//	无
// 功能描述:设置 IO 端口,使串口能够有效使用
// 引用:在SL_Init( )中调用
// ********************************************************************
VOID S2410_SetIrDAIOP( PVOID  pHead )
{
	volatile PSERARCH_INFO   pInfoSerArch   = (PSERARCH_INFO)pHead;

	switch( pInfoSerArch->dwIndex )
	{
	case ID_COM1:
		pInfoSerArch->pGPIO->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6); // clear uart 0 - rx, tx, rts, cts

⌨️ 快捷键说明

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