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

📄 ser_arch.c

📁 基于三星S3C2410的串口驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		pInfoSerArch->pGPIO->rGPHCON |= (0x2<<0 | 0x2<<2 | 0x2<<4 | 0x2<<6); 
		pInfoSerArch->pGPIO->rGPHUP  |= (0x1<<0 | 0x1<<1 | 0x1<<2 | 0x1<<3);
		break;
	case ID_COM2:
		pInfoSerArch->pGPIO->rGPHCON &= ~((3 << 8) | (3 << 10));	// Configure GPH2 and GHP3 for UART1 Tx and Rx, respectively.
		pInfoSerArch->pGPIO->rGPHCON |=  ((2 << 8) | (2 << 10));	// Enable GHP3 for RXD0 and GHP2 for TXD0
		pInfoSerArch->pGPIO->rGPHUP |= (1 << 4) | (1 << 5);						// pull-up functio
		break;
	}
}

// ********************************************************************
// 声明:void	ser_CloseMode( PSERARCH_INFO pInfoSerArch )
// 参数:
//	IN pInfoSerArch-ARCH信息
// 返回值:
//	无
// 功能描述:硬件关闭
// 引用: 
// ********************************************************************
//close hardware function
void	ser_CloseMode( PSERARCH_INFO pInfoSerArch )
{
	//
#ifndef CANCEL_XYG_SER_RX
	EnterCriticalSection(&(pInfoSerArch->csBufRW));
	RWBuf_SetZero( pInfoSerArch->lpRWBuf, FALSE );
	LeaveCriticalSection(&(pInfoSerArch->csBufRW));
#endif

	//EnterCriticalSection(&(pInfoSerArch->RegCritSec));

	//关闭MODEM引脚
	//if( pInfoSerArch->dwOpt & OPT_MODEM )
	{
		SerArch_ClearPinRTS( pInfoSerArch );
	}

	// Disable all interrupts and clear MCR.
	DisEnSubINT(pInfoSerArch, (pInfoSerArch->bRxINT|pInfoSerArch->bTxINT|pInfoSerArch->bErrINT));
	pInfoSerArch->fSW_EnTxINT = FALSE;

	// This routhine for auto detect.
	S2410_SetIrDAIOP(pInfoSerArch);	//设置硬件恢复到初始化状态

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

//-----------------------------------------
// ********************************************************************
// 声明:PVOID	SerArch_Init( ULONG Identifier, PVOID pHeadDrv, PVOID lpDCB )
// 参数:
//	IN Identifier-上层传递的参数
//	IN pHeadDrv-上层传递的参数
//	IN lpDCB-上层传递的参数
// 返回值:
//	无
// 功能描述:硬件初始化
// 引用: 
// ********************************************************************
PVOID	SerArch_Init( ULONG Identifier, PVOID pHeadDrv, PVOID lpDCB )
{
    PSERARCH_INFO	pInfoSerArch;

    RETAILMSG(1,TEXT("\r\n++++++++++SerArch_Init Start!++++++++++++\r\n"));
	//分配结构
    pInfoSerArch = (PSERARCH_INFO)malloc( sizeof(SERARCH_INFO) );
	if( pInfoSerArch==NULL )
		return NULL;
	memset( pInfoSerArch, 0, sizeof(SERARCH_INFO) );

	//初始化---
	InitializeCriticalSection(&(pInfoSerArch->csTransmit));
	//InitializeCriticalSection(&(pInfoSerArch->RegCritSec));

	//初始化---硬件信息
	if( ser_InitInfoOfHardware(pInfoSerArch, Identifier) )//保证硬件存在
	{
		//初始化---上层信息
		pInfoSerArch->pHeadDrv = pHeadDrv;
	    pInfoSerArch->lpfnEventNotify = ser_NotifyCommEvent;
		//初始化---硬件
		//if( pInfoSerArch->dwIoBase!=UART_DEBUGPORT )//调试的串口
		{
			ser_CloseMode( pInfoSerArch );
		}

		//初始化---硬件
		pInfoSerArch->dwOpenCount= 0;
		pInfoSerArch->lpDCB    = (DCB*)lpDCB;
		//pInfoSerArch->fWaitTxim  = 0;
		pInfoSerArch->hEvtXMit   = CreateEvent(0, FALSE, FALSE, NULL);

		//初始化---中断ISR
		pInfoSerArch->hEvtISR = CreateEvent( NULL, FALSE, FALSE, NULL );
		INTR_Init( pInfoSerArch->dwISR, pInfoSerArch->hEvtISR, NULL, 0 );//pInfoDrv->pObjDev->dwIntID注册中断
		INTR_Disable( pInfoSerArch->dwISR );//pInfoDrv->pObjDev->dwIntID注册中断
		ResetEvent( pInfoSerArch->hEvtISR );

		//if( pInfoSerArch->pObjDev->BindFlags==THREAD_AT_INIT )
		pInfoSerArch->hThrdISR = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ser_WaitInterrupt, (LPVOID)pInfoSerArch, 0, &pInfoSerArch->dwThrdISR );
		if( !pInfoSerArch->hThrdISR )
		{
			SerArch_Deinit( pInfoSerArch );
			return NULL;
		}
		
//		RETAILMSG(1,TEXT("\r\nSerArch_Init() over\r\n"));
		SetThreadPriority( pInfoSerArch->hThrdISR, THREAD_PRIORITY_TIME_CRITICAL );
		//SetThreadPolicy( pInfoSerArch->hThrdISR, STP_ROTATION );//2004-03-18

		//
#ifdef	DEBUG_SERARCH
		g_pDebugSerArch = pInfoSerArch;
#endif

#ifdef	DEBUG_SERARCH
		RETAILMSG(1,TEXT("\r\n SerArch_Init() ---- Debug_Arch \r\n"));
	Debug_Arch( pInfoSerArch );
#endif
		return pInfoSerArch;
	}

	free( pInfoSerArch );
	return NULL;
}

// ********************************************************************
// 声明:DWORD	WINAPI	ser_WaitInterrupt( DWORD  pHead )
// 参数:
//	IN pHead-ARCH信息
// 返回值:
//	0
// 功能描述:硬件中断服务例程
// 引用: 
// ********************************************************************
//interrupt service route
static volatile DRIVER_GLOBALS * const lpGlobal =(DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START;
DWORD	WINAPI	ser_WaitInterrupt( DWORD  pHead )
{
    PSERARCH_INFO	pInfoSerArch = (PSERARCH_INFO)pHead;

	SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
	while( !pInfoSerArch->fExitISR )
	{
		{		
			UINT LineStatus = 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("uo-b.\r\n")));
			}
		}
		
		WaitForSingleObject( pInfoSerArch->hEvtISR, INFINITE );
		if( pInfoSerArch->fExitISR )
			break;
		if( lpGlobal->dwSysTickCount-lpGlobal->dwUartTickCount > 1 )
		{
			RETAILMSG(1,(TEXT("tickDiff=0x%x.\r\n"),lpGlobal->dwSysTickCount-lpGlobal->dwUartTickCount));
		}
		
		
		{		
			UINT LineStatus = 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("uo-e,diff=0x%x.\r\n"),lpGlobal->dwSysTickCount-lpGlobal->dwUartTickCount));
				
			}
		}
		

		ser_HandleInterrupt( pInfoSerArch->pHeadDrv );
		INTR_Done( pInfoSerArch->dwISR );
	}
	return 0;
}

// ********************************************************************
// 声明:BOOL	ser_InitInfoOfHardware( PSERARCH_INFO pInfoSerArch, ULONG Identifier )
// 参数:
//	IN pInfoSerArch-ARCH信息
//	IN Identifier-上层传递的参数
// 返回值:
//	成功返回TRUE
// 功能描述:此函数初始化串口硬件地址和功能(读取注册表 或者直接初始化指定);保证硬件存在
// 引用: 
// ********************************************************************
//init hardware information
BOOL	ser_InitInfoOfHardware( PSERARCH_INFO pInfoSerArch, ULONG Identifier )
{
	//指定硬件的指针和功能
	switch( Identifier )
	{
	case ID_COM1://
		//串口硬件功能信息
		pInfoSerArch->dwIndex= ID_COM1;
		pInfoSerArch->dwIoBase= UART0_BASE;//2004-03-18
		pInfoSerArch->dwISR  = SYSINTR_SERIAL;

		//pInfoSerArch->dwComFun	= COM_UART;
//		pInfoSerArch->pBaudTbl= (BAUDTBL *)&LS_BaudTable;

		//pInfoSerArch->dwOpt |= OPT_MODEM;//2004-03-18

		pInfoSerArch->bINT		= BIT_UART0;	//#define   BIT_UART0       ( 0x1 << 28 )
		pInfoSerArch->bTxINT	= INTSUB_TXD0;	//#define	INTSUB_TXD0		( 0x1 << 1  )
		pInfoSerArch->bRxINT	= INTSUB_RXD0;	//#define 	INTSUB_RXD0		( 0x1 << 0  )
		pInfoSerArch->bErrINT	= INTSUB_ERR0;	//#define	INTSUB_ERR0		( 0x1 << 2  )

#ifndef CANCEL_XYG_SER_RX
		pInfoSerArch->lpRWBuf = &lpGlobal->stSerRx0;
		InitializeCriticalSection(&(pInfoSerArch->csBufRW));
#endif
		break;

	case ID_COM2:
		//串口硬件功能信息
		pInfoSerArch->dwIndex= ID_COM2;
		pInfoSerArch->dwIoBase= UART1_BASE;//2004-03-18
		pInfoSerArch->dwISR  = SYSINTR_IR;

		//pInfoSerArch->dwComFun	= COM_UART;
//		pInfoSerArch->pBaudTbl= (BAUDTBL *)&LS_BaudTable;

		//pInfoSerArch->dwOpt |= OPT_MODEM;//2004-03-18

		pInfoSerArch->bINT		= BIT_UART1;	//#define   BIT_UART0       ( 0x1 << 28 )
		pInfoSerArch->bTxINT	= INTSUB_TXD1;	//#define	INTSUB_TXD0		( 0x1 << 1  )
		pInfoSerArch->bRxINT	= INTSUB_RXD1;	//#define 	INTSUB_RXD0		( 0x1 << 0  )
		pInfoSerArch->bErrINT	= INTSUB_ERR1;	//#define	INTSUB_ERR0		( 0x1 << 2  )

#ifndef CANCEL_XYG_SER_RX
		pInfoSerArch->lpRWBuf = &lpGlobal->stSerRx1;
		InitializeCriticalSection(&(pInfoSerArch->csBufRW));
#endif
		break;

	default ://如果该硬件不存在,则取消
		return FALSE;
	}

	//设备属性
	pInfoSerArch->CommProp.wPacketLength      = 0xffff;
	pInfoSerArch->CommProp.wPacketVersion     = 0xffff;
	pInfoSerArch->CommProp.dwServiceMask      = SP_SERIALCOMM;
	pInfoSerArch->CommProp.dwMaxBaud          = BAUD_115200;
	pInfoSerArch->CommProp.dwProvSubType      = PST_RS232;
	pInfoSerArch->CommProp.dwSettableBaud     =
		BAUD_075  | BAUD_110 | BAUD_150 | BAUD_300 | BAUD_600 |
		BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 | BAUD_7200 | 
		BAUD_9600 | BAUD_14400 | BAUD_19200  | BAUD_38400 | 
		BAUD_56K | BAUD_128K | BAUD_115200 | BAUD_57600;
	pInfoSerArch->CommProp.wSettableData      =	DATABITS_7 | DATABITS_8;
	pInfoSerArch->CommProp.wSettableStopParity=	PARITY_NONE | PARITY_ODD | PARITY_EVEN;
	pInfoSerArch->CommProp.dwProvCapabilities =	
		PCF_SETXCHAR |PCF_SPECIALCHARS |PCF_XONXOFF |PCF_PARITY_CHECK
		|PCF_INTTIMEOUTS |PCF_TOTALTIMEOUTS;
	pInfoSerArch->CommProp.dwSettableParams   =
		SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY | 
		SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;
	//if( pInfoSerArch->dwOpt & OPT_MODEM )
	{
		//添加 硬件握手
		//pInfoSerArch->CommProp.dwProvCapabilities |= PCF_DTRDSR |PCF_RLSD |PCF_RTSCTS;
		pInfoSerArch->CommProp.dwProvCapabilities |= PCF_RTSCTS;
	}

	//绑定到虚拟地址
	pInfoSerArch->pUART = (volatile PS2410_UART_REG)pInfoSerArch->dwIoBase;
	pInfoSerArch->pGPIO = (volatile IOPreg *)IOP_BASE;
	pInfoSerArch->pIrqCtrlAddr = (volatile INTreg*)INT_BASE;

	// 数据寄存器
	pInfoSerArch->pUFTXH = (volatile unsigned char *)&(pInfoSerArch->pUART->rUTXH);	//传输寄存器
	pInfoSerArch->pUFRXH = (volatile unsigned char *)&(pInfoSerArch->pUART->rURXH);	//接收寄存器

	// 关联中断寄存器
	pInfoSerArch->UART_INTMASK		= (volatile unsigned int *)&(pInfoSerArch->pIrqCtrlAddr->rINTMSK);
	pInfoSerArch->UART_INTSUBMASK	= (volatile unsigned int *)&(pInfoSerArch->pIrqCtrlAddr->rINTSUBMSK);
	pInfoSerArch->UART_INTPND		= (volatile unsigned int *)&(pInfoSerArch->pIrqCtrlAddr->rINTPND);
	pInfoSerArch->UART_INTSRCPND		= (volatile unsigned int *)&(pInfoSerArch->pIrqCtrlAddr->rSRCPND);
	pInfoSerArch->UART_INTSUBSRCPND	= (volatile unsigned int *)&(pInfoSerArch->pIrqCtrlAddr->rSUBSRCPND);

	//osm2 timer: 成关闭状态,并初始化
	//WRITE_BITFIELD(struct icregBits,&pInfoSerArch->pIrqCtrlAddr->icmr,osmr2,0);
	//WRITE_BITFIELD(struct icregBits,&(pInfoSerArch->pIrqCtrlAddr)->iclr,osmr2,0);
	//IOW_REG_BITWRITE (struct matchRegBits, &(pInfoSerArch->pOSTReg)->ossr,m2,1);
	//WRITE_BITFIELD(struct matchRegBits, &(pInfoSerArch->pOSTReg)->oier,m2,0);

	pInfoSerArch->pBaudTbl		= (BAUDTBL *)&LS_BaudTable;//各个baud都一样
	pInfoSerArch->dwSizeTbl		= BAUD_TABLE_SIZE;//各个baud都一样

	return TRUE;
}

//reserved for the last init hardware
VOID	SerArch_InitLast( PVOID   pHead )
{
}

// ********************************************************************
// 声明:BOOL	SerArch_Deinit( PVOID   pHead )
// 参数:
//	IN pHead-ARCH信息
// 返回值:
//	成功返回TRUE
// 功能描述:串口释放
// 引用: 
// ********************************************************************
//the entry of deinit
BOOL	SerArch_Deinit( PVOID   pHead )
{
    PSERARCH_INFO pInfoSerArch = (PSERARCH_INFO)pHead;

    if(!pInfoSerArch)
	{
        return(FALSE);
	}

    if(pInfoSerArch->dwOpenCount)
	{
		SerArch_Close(pHead);
	}
	//
    DeleteCriticalSection(&(pInfoSerArch->csTransmit));
	if( pInfoSerArch->hEvtXMit )
		CloseHandle( pInfoSerArch->hEvtXMit );
	//
	pInfoSerArch->fExitISR = TRUE;
	SetEvent( pInfoSerArch->hEvtISR );
	Sleep( 10 );
	if( pInfoSerArch->hEvtISR )
		CloseHandle( pInfoSerArch->hEvtISR );
	if( pInfoSerArch->hThrdISR )
		CloseHandle( pInfoSerArch->hThrdISR );

    free(pInfoSerArch);
    return(TRUE);
}

//-----------------------------------------
// ********************************************************************
// 声明:ULONG	SerArch_Close( PVOID   pHead )
// 参数:
//	IN pHead-ARCH信息
// 返回值:
//	0
// 功能描述:串口关闭
// 引用: 
// ********************************************************************
ULONG	SerArch_Close( PVOID   pHead )
{
    PSERARCH_INFO   pInfoSerArch = (PSERARCH_INFO)pHead;
    ULONG  uTries;
    
    if( pInfoSerArch->dwOpenCount )
    {
        pInfoSerArch->dwOpenCount--;

        // while we are still transmitting, sleep.
		while((pInfoSerArch->pUART->rUFSTAT & SER2410_FIFOSTAT_MASK) & (uTries++ < 100))
		{	// TxFifo not empty..
			Sleep(10);
		}

		//close hardware
		if( pInfoSerArch->dwOpenCount==0 )
		{
			//RETAILMSG( 1, (TEXT("xyg call ser_CloseMode\r\n")) );
			//if( pInfoSerArch->dwIoBase!=UART_DEBUGPORT )//because it is debug serial
				ser_CloseMode( pInfoSerArch );
		}
	}

//#ifdef	DEBUG_SERARCH
//	SerDebug_Enable( DEBUGTO_SERIAL );
//#endif
    return(0);
}

// ********************************************************************
// 声明:static void SerSetOutputMode( PSERARCH_INFO pInfoSerArch, BOOL UseIR )
// 参数:
//	IN PSERARCH_INFO pInfoSerArch - PDD层全局结构
//	IN BOOL UseIR - 红外线(NONE)
// 返回值:
//	无
// 功能描述:是否使用红外线(没有红外线功能)
// 引用:由 SerArch_Init( ) 中调用
// ********************************************************************
static void SerSetOutputMode( PSERARCH_INFO pInfoSerArch, BOOL UseIR )
{
	volatile	PSERARCH_INFO   pHWHead2   = (PSERARCH_INFO)pInfoSerArch;

	if (UseIR)
	{
		CLEARREG(pHWHead2,rULCON,SER2410_IRMODE_MASK);   // Infra-red mode enable.
	}
	else
	{
		CLEARREG(pHWHead2,rULCON,SER2410_IRMODE_MASK);   // Infra-red mode disable.
	}
}

⌨️ 快捷键说明

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