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

📄 sccahdlcdrv.c

📁 支持VXWORKES操作系统下MPC860系列处理器地异步HDLC驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
void sccParaInit(SCC_AHDLC_DEV *pSccDev){	volatile SCC_AHDLC_PARAM * pPram;	pPram = pSccDev->pscc_params;	/* rx/tx BD table base address -- offset from the beginning of dual-port RAM */	pPram->param.rbase = pSccDev->recvBD_base;	pPram->param.tbase = pSccDev->transBD_base;	pPram->param.rfcr = 0x10;		/*Big-endian or true little-endian.*/	pPram->param.tfcr = 0x10;		/*Big-endian or true little-endian.*/	pPram->param.mrblr = SCC_AHDLC_MRBLR;	pPram->param.rstate = 0;	pPram->param.res1 = 0;	pPram->param.rbptr = 0;	pPram->param.res2 = 0;	pPram->param.res3 = 0;	pPram->param.tstate = 0;	pPram->param.res4 = 0;	pPram->param.tbptr = 0;	pPram->param.res5 = 0;	pPram->param.res6 = 0;	pPram->param.rcrc = 0;	pPram->param.tcrc = 0;	pPram->c_mask = CRC_16_MASK;	pPram->c_pres = CRC_16_PRES;	pPram->bof = 0x7e;	pPram->eof = 0x7e;	pPram->esc = 0x7d;	pPram->zero = 0;	pPram->rfthr = 1;	pPram->txctl_tbl =0;	pPram->rxctl_tbl =0;	pPram->nof        = 0;	      debug(("pPram->param.rfcr = 0x%x , addr = 0x %x \n " , pPram->param.rfcr,&pPram->param.rfcr ) );	if( _eSCCSuccess !=  sccCpcrCommand(CPCR_OPCODE_INITTR_PARA, pSccDev) )	{	      debug(( " sccCpcrCommand error \n "));		return;	}	else 		{			 debug(( " sccCpcrCommand    Success \n "));	  	}}/* *	sccRegInit(sccno) */void sccRegInit(SCC_AHDLC_DEV *pSccDev){	/* clear any previous event */	pSccDev->pscc_regs->scce = 0xffff;		/* write to SCCM to allow interrupt of RXB TXB RXF and BSY */	pSccDev->pscc_regs->sccm = SCC_AHDLC_SCCE_RXB | SCC_AHDLC_SCCE_TXB | SCC_AHDLC_SCCE_RXF		| SCC_AHDLC_SCCE_BSY;	/* Write 0x0000_0000 to GSMR_Hx to enable normal CTS and CD behavior with idles (not flags)		between frames. */	pSccDev->pscc_regs->gsmrh = 0x00000000;	/* Write 0x0000_0000 to GSMR_L2 to configure CTS and CD to control transmission and reception		in HDLC mode.*/	pSccDev->pscc_regs->gsmrl = SCC_GSMRL_AHDLC | SCC_AHDLC_CLCMODE_16 |0x20000000;	pSccDev->pscc_regs->psmr = AHDLC_PSMR_CHLN ;  /* no flow control.*/	  debug(("gsmrl = %x \n  "   , pSccDev->pscc_regs->gsmrl ));	/*  pSccDev->pBaud  =  BRGC4(pSccDev->immrVal) ;*/	*pSccDev->pBaud  = 0;      	*pSccDev->pBaud  |=  (650<<1 ); /*  0x145 set baudrate 9600*/ /*  or 650*/	*pSccDev->pBaud  |= 0 ;/*BRGC_DIV16;*/	*pSccDev->pBaud  |= BRGC_EN;		 debug(("BRG4 = %x \n  "   , *BRGC4(pSccDev->immrVal)));			/* Write to interrupt mask register (CIMR) to allow SCCx to generate a		system interrupt.*/	*CIMR(pSccDev->immrVal) |= CIMR_SCC4;}/* *	SCC4 interrupt service routine  */void scc4hdlcISR(int dev){	INT16	event;	BUFM_BUF * rbuf_p;	SCC_AHDLC_BD * pBD;	int len;	int i;	SCC_AHDLC_DEV *  pSccDev =( SCC_AHDLC_DEV *) dev ;	/* read the interrupt event */	event = pSccDev->pscc_regs->scce;	/* clear the event */	pSccDev->pscc_regs->scce = event;	/* statistics */	/*	pSccDev->statistics.numIsrEnter++;	*/		if(event & SCC_AHDLC_SCCE_RXF)	{				pBD = &pSccDev->precv_BD[pSccDev->current_rBD];            		while( 0 == (AHDLC_BD_RX_EMPTY_BIT & pBD->statusMode ))		{		     			if( pBD->statusMode & 				(AHDLC_BD_RX_BREAK_BIT | AHDLC_BD_RX_FRAME_CLOSE_BIT 				| AHDLC_BD_RX_AB_BIT | AHDLC_BD_RX_CR_BIT				|  AHDLC_BD_RX_OV_BIT ))			{						   				if (  pBD->statusMode &AHDLC_BD_RX_CR_BIT  )					 {					 	 pSccDev->statistics.pnumCrcec++;								#if 0						 logMsg(" %x ,len :%d num %d,add 0x%x\n" , pBD->statusMode ,pBD->dataLength ,pSccDev->current_rBD,(int)pBD->dataPointer);									 for(i =0; i< pBD->dataLength ; i++)							{								 logMsg(" %x\n" ,pBD->dataPointer[i] );							}						 logMsg(" end\n ");				               #endif											#ifdef AHDLC_CRC16						rbuf_p =  &pSccDev->usr_recv_buf[pSccDev->rbuf_wptr];						if( 0 == rbuf_p->status)	/* there are free bufs */							{								len = pBD->dataLength ;								rbuf_p->needcrc  = 1;								debug((  " scc4hdlcISR  pSccDev->current_rBD =%d,  pBD->dataLength = %d , len =%d, rbuf_wptr =%d  \n "  , pSccDev->current_rBD,pBD->dataLength ,len, pSccDev->rbuf_wptr));								bcopy( (const char *)pBD->dataPointer, (char *)rbuf_p->body, len);								rbuf_p->len = len;								rbuf_p->status = 1;								pBD->dataLength =0;								pSccDev->rbuf_wptr++;								if(pSccDev->rbuf_wptr >= SCC_AHDLC_RECV_BUF_NUM)									pSccDev->rbuf_wptr = 0;								pSccDev->ready_to_read = TRUE;								selWakeupAll(  &pSccDev->selWakeupkist , SELREAD);								semGive(  pSccDev->readSem );							}					      #endif					 }	 				 	else if (  pBD->statusMode &AHDLC_BD_RX_BREAK_BIT  ) 				 		   {			 		   	pSccDev->statistics.rx_break++;			 		  	}			 				else if (  pBD->statusMode &AHDLC_BD_RX_FRAME_CLOSE_BIT  ) 				 					{			 						pSccDev->statistics.rx_frame_close++;			 					}				 					else if (  pBD->statusMode &AHDLC_BD_RX_AB_BIT  )			 						{ 				 							pSccDev->statistics.rx_ab++;			 						}			 						else if (  pBD->statusMode &AHDLC_BD_RX_OV_BIT  ) 			 							{			 								pSccDev->statistics.rxov++;			 							}					pSccDev->statistics.total++;							}			else  /*if( (pBD->statusMode  &  BD_RX_FIRSTFRAME_BIT ) == BD_RX_FIRSTFRAME_BIT )	*/						{			      				rbuf_p =  &pSccDev->usr_recv_buf[pSccDev->rbuf_wptr];				if( 0 == rbuf_p->status)	/* there are free bufs */				{					pSccDev->statistics.recive++;					len = pBD->dataLength ;										debug((  " scc4hdlcISR  pSccDev->current_rBD =%d,  pBD->dataLength = %d , len =%d, rbuf_wptr =%d  \n "  , pSccDev->current_rBD,pBD->dataLength ,len, pSccDev->rbuf_wptr));					bcopy( (const char *)pBD->dataPointer, (char *)rbuf_p->body, len);					rbuf_p->len = len;					rbuf_p->status = 1;					pBD->dataLength =0;					pSccDev->rbuf_wptr++;					if(pSccDev->rbuf_wptr >= SCC_AHDLC_RECV_BUF_NUM)						pSccDev->rbuf_wptr = 0;					pSccDev->ready_to_read = TRUE;					selWakeupAll(  &pSccDev->selWakeupkist , SELREAD);					semGive(  pSccDev->readSem );				}										 			}			/* prepare the BD for next recv*/			if( pBD->statusMode & AHDLC_BD_RX_WRAP_BIT)			{				pSccDev->current_rBD = 0;				pBD->statusMode = AHDLC_BD_RX_WRAP_BIT | AHDLC_BD_RX_EMPTY_BIT | AHDLC_BD_RX_INTERRUPT_BIT;			}			else			{				pSccDev->current_rBD++;				pBD->statusMode = AHDLC_BD_RX_EMPTY_BIT | AHDLC_BD_RX_INTERRUPT_BIT;			}			/* check the next BD */			pBD = &pSccDev->precv_BD[pSccDev->current_rBD];					}			}	if(event & SCC_AHDLC_SCCE_TXB)	{		pSccDev->statistics.sent++;				#ifdef AHDLC_USE_TIME3		timer3Enable( );		#else		AHDLC_RX_CS();		semGive ( sccDev[0].writeSem  );			sccDev[0].ready_to_write =TRUE;		selWakeupAll(  &sccDev[0].selWakeupkist , SELWRITE);		#endif	}    }/* *	sccHdlcEnable(sccno) *	Enable scc. */void sccHdlcEnable(SCC_AHDLC_DEV *  pSccDev ){	/* pend interrupt service routine */	#if 0	if(0 == sccno)		(void) intConnect (IV_SCC3, (VOIDFUNCPTR) scc3hdlcISR, 0);	else	#endif		(void) intConnect (IV_SCC4, (VOIDFUNCPTR) scc4hdlcISR, (int) pSccDev );		/* Write 0x00000030 to GSMR_L2 to enable the transmitter and receiver.*/	pSccDev->pscc_regs->gsmrl |= SCC_GSMRL_AHDLC | SCC_GSMRL_ENT | SCC_GSMRL_ENR| 0x20000000;/* | SCC_GSMRL_DIAG_LOOP;*/      }void sccHdlcDisable(SCC_AHDLC_DEV *  pSccDev ){	/* pend interrupt service routine */	#if 0	if(0 == sccno)		(void) intConnect (IV_SCC3, (VOIDFUNCPTR) scc3hdlcISR, 0);	else	#endif			pSccDev->pscc_regs->gsmrl &=  (~(SCC_GSMRL_ENT | SCC_GSMRL_ENR ) ) ;/* | SCC_GSMRL_DIAG_LOOP;*/}/********************************************************************************* ahdlcDrv - initialize the AHDLC driver** SEE ALSO: ahdlcDevCreate()*/STATUS ahdlcDrv  (    )    {    int  i;    /* check if driver already installed */	    if (ahdlcDrvNum > 0)	return (OK);   if ( ( ahdlcDrvNum = iosDrvInstall (ahdlcOpen, (FUNCPTR) NULL, ahdlcOpen,		    ahdlcClose, ahdlcRead, ahdlcWrite, ahdlcIoctl)  ) == ERROR)	   return  (ERROR);	         return (OK);    }/********************************************************************************* ahdlcDevCreate - create a device for an AHDLC port** This routine creates a device for a specified AHDLC port.  Each port* to be used should have exactly one device associated with it by calling* this routine.** For instance, to create the device `/ahdlc/0', the proper call would be:* .CS*     ahdlcDevCreate ("/ahdlc/0", 0);* .CE** RETURNS: OK, or ERROR if the driver is not installed, the channel is* invalid, or the device already exists.** SEE ALSO: ahdlcDrv()*/STATUS ahdlcDevCreate    (    char *devName		/* name to use for this device */    ){	SCC_AHDLC_DEV  * pSccDev;	  	  if (ahdlcDrvNum < 1)		{		errnoSet (_eSCCNoDriver);		return (ERROR);		}   /************************initiian start***********************************************/		pSccDev =  sccDev;		/* clear sccDev */		memset(  pSccDev ,  0 ,  sizeof(SCC_AHDLC_DEV) );	 	selWakeupListInit ( & pSccDev ->selWakeupkist); 		 init_ports();				pSccDev->immrVal = vxImmrGet();				debug(("pSccDev->immrVal = %x \n" ,  pSccDev->immrVal  ));		  /*分配用户缓冲区*/		pSccDev->usr_recv_buf = usrbuf ;			       memset( ( char * ) pSccDev->usr_recv_buf , 0,  sizeof(BUFM_BUF)*SCC_AHDLC_RECV_BUF_NUM);			 /*  初始化BD 缓冲区指针*/		 #ifdef USE_DMA		if(NULL == (pSccDev->ptran_buf_malloc_address = (unsigned char *)cacheDmaMalloc(SCC_AHDL_FRAME_SIZE*SCC_NUM_TBD )))		{			errnoSet (_eSCCNoCachMemory);			debug((" cacheDmaMalloc: ptran_buf_malloc_address errot \n"));			goto errExit;		}					if(NULL == (pSccDev->precv_buf_malloc_address = (unsigned char *)cacheDmaMalloc(SCC_AHDL_FRAME_SIZE*SCC_NUM_RBD )))		{			errnoSet (_eSCCNoCachMemory);			debug((" cacheDmaMalloc: precv_buf_malloc_address errot \n"));			goto errExit;		}			    	pSccDev->ptran_buf_base = (unsigned char*)   (  (unsigned int )  pSccDev->ptran_buf_malloc_address );		pSccDev->precv_buf_base = (unsigned char*)   (  (unsigned int ) pSccDev->precv_buf_malloc_address);		#else		pSccDev->ptran_buf_base  =   (unsigned char *)  txpbbuf ;		 pSccDev->precv_buf_base =  (unsigned char *)  rxpbbuf ;		#endif 							 /* 初始化参数寄存器指针*/		pSccDev->pscc_params = (volatile SCC_AHDLC_PARAM *)(MPC860_DPR_SCC4(pSccDev->immrVal));		pSccDev->pscc_regs = (volatile SCC_REG *)(GSMR_L4(pSccDev->immrVal));			/*初始化波特率寄存器指针*/		 pSccDev->pBaud  =  BRGC4(pSccDev->immrVal);                	/* 初始化 发送和接收BD 指针*/		pSccDev->transBD_base = SCC4_AHDLC_BD_BASE;		pSccDev->ptran_BD = (SCC_AHDLC_BD *)(SCC4_AHDLC_BD_BASE + pSccDev->immrVal);		pSccDev->current_tBD = 0;				pSccDev->recvBD_base = SCC4_AHDLC_BD_BASE + SCC_BD_SZ*SCC_NUM_TBD;		pSccDev->precv_BD = (SCC_AHDLC_BD *)(SCC4_AHDLC_BD_BASE + pSccDev->immrVal + SCC_BD_SZ*SCC_NUM_TBD);		pSccDev->current_rBD = 0;						init_tranBD(pSccDev);		init_recvBD(pSccDev);		sccParaInit(pSccDev);		/* initialize parameter of hdlc */		sccRegInit(pSccDev);		/* initialize registers of HDLC */		#ifdef AHDLC_USE_TIME3	       timer3initial( ); 		#endif            		  		debug(( "sccDevCreate  finished \n " ));

⌨️ 快捷键说明

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